首页 > 解决方案 > 即使我调整主窗口的大小,QWidget.rect 的大小也不会改变

问题描述

我有一个主窗口,我想在该窗口中应用一些 QEvent 鼠标事件,例如移动按下...等,我的问题是在创建应用程序和主窗口后我调整了它的大小,但是当我调用 rect()来自 QWidget 的函数它实际上给了我默认值(0、0、100、30),我希望它给我窗口的大小。

class TestTools(unittest.TestCase):
    app = QApplication([])
    main_window = QMainWindow()
    main_window.resize(958, 584)
    scene = QGraphicsScene()
    canvas = Canvas(scene, main_window)
    print(canvas.rect()) # It Print (0, 0, 100, 30) Whereas it should be (0, 0, 958, 584)
    
    def test():
       pass # There is many functions am using but I don't think it is important to share it

这是画布类

class Canvas(QGraphicsView):
def __init__(self, scene, centralwidget):
    super().__init__(scene, centralwidget)

    self.scene = scene
    background_color = Qt.white
    self.pixmap_item: QGraphicsItem = self.scene.addPixmap(QPixmap(780, 580))
    self.pixmap_item.setTransformationMode(Qt.FastTransformation)

那么问题出在哪里。

标签: pythonpython-3.xpyqt5qwidget

解决方案


您是基于错误的前提做出假设。

首先,您只是在创建一个带有父级的小部件(QGraphicsView)。这样做只会使窗口小部件成为该父窗口的子窗口,但没有任何大小限制:窗口小部件只是在其父窗口内“浮动”,因此它的默认大小通常为新子窗口小部件的 100x30(窗口小部件为 640x480)在构造函数中没有设置父级))。

如果要将子级调整为父级,则必须将其添加到布局中。QMainWindow 有自己的(私有)布局管理器,它使用中央小部件来显示窗口的“主要”内容,因此如果 QGraphicsView 将成为唯一的小部件,您可以使用main_window.setCentralWidget(canvas).

然后,小部件在第一次映射之前通常不会收到 resizeEvent,除非它是手动调整大小的。当它第一次显示时,任何非先前布局的项目都会收到调整大小事件。由于您没有显示主窗口,因此不会发出调整大小事件,但即使在这种情况下,您在添加子窗口之前调整了窗口大小,因此您仍然会看到相同的默认大小。

为了确保即使显示设置它的小部件也能正确计算布局,activate()必须显式调用。

所以,总结一下:

  • 必须将小部件添加到布局中以使其大小适应其父级;
  • 每当使用 QMainWindow 时,setCentralWidget() 必须在“主窗口小部件”上使用;
  • 将子级添加到布局后进行手动调整大小,以确保其几何形状适应父级(如果您执行相反的操作,某些尺寸策略可能会导致父级根据子级调整自身大小);
  • 如果不显示小部件,则必须手动激活布局;
class TestTools(unittest.TestCase):
    app = QApplication([])
    main_window = QMainWindow()
    scene = QGraphicsScene()
    canvas = Canvas(scene, main_window)
    main_window.setCentralWidget(canvas)
    main_window.resize(958, 584)
    main_window.layout().activate()
    print(canvas.rect())

推荐阅读