即使我调整主 window 的大小,QWidget.rect 的大小也没有改变
Size of QWidget.rect doesn't change even when I resize the main window
我有一个 Main window,我想在那个 window 鼠标事件中应用一些 QEvent,例如移动按下...等,我的问题是在我创建应用程序和 main window 我调整了它的大小,但是当我调用来自 QWidget 的 rect() 函数时,它实际上给了我默认值 (0, 0, 100, 30),我希望它给我 window.
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
这是 Canvas Class
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)
那么问题出在哪里呢
你的假设是基于错误的前提。
首先,您只是在创建一个带有父级的小部件(QGraphicsView)。这样做只会使小部件成为该父部件的子部件,但没有任何大小限制:小部件只是在其父部件内“浮动”,因此它将具有默认大小,新子部件通常为 100x30(小部件为 640x480)构造函数中没有父集)).
如果您想根据父级调整子级,必须将其添加到布局中。 QMainWindow 有自己的 (private) 布局管理器,它使用 central widget 来显示 window 的“主要”内容,所以如果该 QGraphicsView 将成为唯一的小部件,您可以使用 main_window.setCentralWidget(canvas)
.
进行设置
然后,小部件通常在第一次映射之前不会收到 resizeEvent,除非它被手动调整大小。当它第一次显示时,任何以前未布局的项目都会收到调整大小事件。由于您没有显示主要的 window,因此不会发出调整大小事件,但即使在那种情况下,您在添加子项之前调整了 window 的大小,所以您仍然会看到相同的默认大小。
为了确保即使 没有 显示设置它的小部件也能正确计算布局,必须显式调用 activate()
。
所以,总结一下:
- 必须将小部件添加到布局中才能使其大小适应父级;
- 每当使用 QMainWindow 时,
setCentralWidget()
必须 在“主窗口部件”上使用;
- 应在 将子级添加到布局后进行手动调整大小,以确保它们的几何形状适应父级(如果您执行相反的操作,某些尺寸策略可能会导致父级根据子级自行调整大小);
- 如果小部件不显示,必须手动激活布局;
class TestTools(unittest.TestCase):
app = QApplication([])
main_window = QMainWindow()
scene = QGraphicsScene()
canvas = Canvas(scene, main_window)
<b>main_window.setCentralWidget(canvas)
main_window.resize(958, 584)
main_window.layout().activate()</b>
print(canvas.rect())
我有一个 Main window,我想在那个 window 鼠标事件中应用一些 QEvent,例如移动按下...等,我的问题是在我创建应用程序和 main window 我调整了它的大小,但是当我调用来自 QWidget 的 rect() 函数时,它实际上给了我默认值 (0, 0, 100, 30),我希望它给我 window.
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
这是 Canvas Class
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)
那么问题出在哪里呢
你的假设是基于错误的前提。
首先,您只是在创建一个带有父级的小部件(QGraphicsView)。这样做只会使小部件成为该父部件的子部件,但没有任何大小限制:小部件只是在其父部件内“浮动”,因此它将具有默认大小,新子部件通常为 100x30(小部件为 640x480)构造函数中没有父集)).
如果您想根据父级调整子级,必须将其添加到布局中。 QMainWindow 有自己的 (private) 布局管理器,它使用 central widget 来显示 window 的“主要”内容,所以如果该 QGraphicsView 将成为唯一的小部件,您可以使用 main_window.setCentralWidget(canvas)
.
然后,小部件通常在第一次映射之前不会收到 resizeEvent,除非它被手动调整大小。当它第一次显示时,任何以前未布局的项目都会收到调整大小事件。由于您没有显示主要的 window,因此不会发出调整大小事件,但即使在那种情况下,您在添加子项之前调整了 window 的大小,所以您仍然会看到相同的默认大小。
为了确保即使 没有 显示设置它的小部件也能正确计算布局,必须显式调用 activate()
。
所以,总结一下:
- 必须将小部件添加到布局中才能使其大小适应父级;
- 每当使用 QMainWindow 时,
setCentralWidget()
必须 在“主窗口部件”上使用; - 应在 将子级添加到布局后进行手动调整大小,以确保它们的几何形状适应父级(如果您执行相反的操作,某些尺寸策略可能会导致父级根据子级自行调整大小);
- 如果小部件不显示,必须手动激活布局;
class TestTools(unittest.TestCase):
app = QApplication([])
main_window = QMainWindow()
scene = QGraphicsScene()
canvas = Canvas(scene, main_window)
<b>main_window.setCentralWidget(canvas)
main_window.resize(958, 584)
main_window.layout().activate()</b>
print(canvas.rect())