首页 > 解决方案 > Qt5中show()后QGraphicsView/QGraphicsScene初始定位的基本问题

问题描述

我编写了一些用于板可视化的代码,但初始化有问题。我想从头到尾生成充满木板的视图(是否显示在第三张图片上)。我尝试使用许多 Qt5 方法但没有结果(我是 Qt5 的初学者)。第一次调整大小后,视图看起来很完美。

我不知道我在初始化时做错了什么。

就在 .show() 之后:

在此处输入图像描述

失去焦点后(我转而写这个问题):

在此处输入图像描述

调整大小后,它应该看起来像/我想要实现的目标: 在此处输入图像描述

如何修复此代码以使其在初始化时工作 - 我是 Qt5 中的第 1 级(初学者)和编程中的第 7 级。也许它需要非常简单的改变。

这是 Python 3.8/Qt5 的工作代码:

import logging
import sys
import typing

from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QSize, QPoint, Qt, QRect, QMargins
from PyQt5.QtGui import QFont, QPaintEvent, QPainter, QBrush, QColor, QPen
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QSizePolicy, QVBoxLayout, QHBoxLayout, QGraphicsWidget, \
    QGraphicsScene, QGraphicsView, QGraphicsGridLayout, QStyleOptionGraphicsItem, QGraphicsSceneMouseEvent


class Application(QApplication):
    pass


class SquareWidget(QGraphicsWidget):
    def __init__(self, color):
        super().__init__()
        if color:
            self.color = QtCore.Qt.white
        else:
            self.color = QtCore.Qt.black

    def paint(self, painter: QtGui.QPainter, option: QStyleOptionGraphicsItem, widget: typing.Optional[QWidget] = ...) -> None:
        painter.fillRect(option.rect, self.color)


class BoardContainer(QGraphicsWidget):
    def __init__(self):
        super().__init__()
        logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)

        grid = QGraphicsGridLayout()
        grid.setSpacing(0)
        grid.setContentsMargins(0, 0, 0, 0)
        self.setLayout(grid)
        for row in range(8):
            for column in range(8):
                square_widget = SquareWidget((row + column) % 2)
                grid.addItem(square_widget, row, column)


class BoardScene(QGraphicsScene):
    def __init__(self):
        super().__init__()

        self.board_container = board_container = BoardContainer()
        self.addItem(board_container)


class BoardView(QGraphicsView):
    def __init__(self):
        super().__init__()
        logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)

        scene = BoardScene()
        self.setScene(scene)
        # no frame
        self.setFrameShape(0)
        # transparent background
        # self.setStyleSheet('QGraphicsView {background: transparent;}')
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
        super().resizeEvent(event)
        self.fitInView(self.scene().board_container, Qt.KeepAspectRatio)


class BoardWidget(QWidget):
    def __init__(self):
        super().__init__()
        logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)

        grid = QGridLayout()

        board_view = BoardView()
        grid.addWidget(board_view, 0, 0)

        self.setLayout(grid)


def main():
    # show exceptions
    def excepthook(cls, exception, traceback):
        sys.__excepthook__(cls, exception, traceback)
    sys.excepthook = excepthook

    logging.basicConfig(level=logging.DEBUG)
    app = Application(sys.argv)
    app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)

    default_font = QFont()
    default_font.setPointSize(12)
    app.setFont(default_font)

    board_widget = BoardWidget()
    board_widget.setMinimumSize(640, 640)
    board_widget.show()

    sys.exit(app.exec())


if __name__ == '__main__':
    main()

标签: pythonpython-3.xpyqt5qt5

解决方案


试试看:

import logging
import sys
import typing

from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QSize, QPoint, Qt, QRect, QMargins
from PyQt5.QtGui import QFont, QPaintEvent, QPainter, QBrush, QColor, QPen
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QSizePolicy, QVBoxLayout, QHBoxLayout, QGraphicsWidget, \
    QGraphicsScene, QGraphicsView, QGraphicsGridLayout, QStyleOptionGraphicsItem, QGraphicsSceneMouseEvent


class Application(QApplication):
    pass


class SquareWidget(QGraphicsWidget):
    def __init__(self, color):
        super().__init__()

        self.resize(640, 640)                                    # +++        

        if color:
            self.color = QtCore.Qt.white
        else:
            self.color = QtCore.Qt.black

    def paint(self, painter: QtGui.QPainter, option: QStyleOptionGraphicsItem, widget: typing.Optional[QWidget] = ...) -> None:
        painter.fillRect(option.rect, self.color)


class BoardContainer(QGraphicsWidget):
    def __init__(self):
        super().__init__()
        logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)

        self.resize(640, 640)                                     # +++
        self.setMinimumSize(80, 80)                               # +++       


        grid = QGraphicsGridLayout()
        grid.setSpacing(0)
        grid.setContentsMargins(0, 0, 0, 0)
        self.setLayout(grid)
        for row in range(8):
            for column in range(8):
                square_widget = SquareWidget((row + column) % 2)
                grid.addItem(square_widget, row, column)


class BoardScene(QGraphicsScene):
    def __init__(self):
        super().__init__()

        self.board_container = board_container = BoardContainer()
        self.addItem(board_container)


class BoardView(QGraphicsView):
    def __init__(self):
        super().__init__()
        logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)

        scene = BoardScene()
        self.setScene(scene)
        # no frame
        self.setFrameShape(0)
        # transparent background
        # self.setStyleSheet('QGraphicsView {background: transparent;}')
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
        super().resizeEvent(event)
        self.fitInView(self.scene().board_container, Qt.KeepAspectRatio)


class BoardWidget(QWidget):
    def __init__(self):
        super().__init__()
        logging.debug('size is %s for %s.', self.size(), self.__class__.__name__)

        grid = QGridLayout()

        board_view = BoardView()
        grid.addWidget(board_view, 0, 0)

        self.setLayout(grid)


def main():
    # show exceptions
    def excepthook(cls, exception, traceback):
        sys.__excepthook__(cls, exception, traceback)
    sys.excepthook = excepthook

    logging.basicConfig(level=logging.DEBUG)
    app = Application(sys.argv)
    app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)

    default_font = QFont()
    default_font.setPointSize(12)
    app.setFont(default_font)

    board_widget = BoardWidget()
    board_widget.setMinimumSize(640, 640)
    board_widget.show()

    sys.exit(app.exec())


if __name__ == '__main__':
    main()

在此处输入图像描述


推荐阅读