使用Qt5,我试图使用绝对定位使小部件正常工作。下面的代码是我正在尝试做的最小工作示例。快速浏览代码:
CentralWidget
是主窗口的中央窗口小部件,并使用绝对定位(例如:不使用任何布局。 MyWidget
不会立即设置其子窗口小部件,但是提供了一种MyWidget
方法,该方法首先删除所有当前的子窗口小部件,然后将新的子窗口小部件添加到其布局中。SetData
使用主窗口中的计时器触发。我注释掉两行代码。通过向SetData
添加布局,第一个“启用”使用布局的相对定位。此行显示了我要实现的目标,但具有绝对的定位。第二条注释启用了一些调试信息:
CentralWidget
为了通过绝对定位显示MyWidget
layout.count: 3
size: PyQt5.QtCore.QSize(-1, -1)
sizeHint: PyQt5.QtCore.QSize(200, 100)
CentralWidget
size: PyQt5.QtCore.QSize(18, 18)
sizeHint: PyQt5.QtCore.QSize(18, 18)
,我做错了什么?
代码:
MyWidget
此行为的原因直接与未将小部件添加到布局的事实有关。和在显示后添加其内容。
实际上,如果在初始化时以及在from PyQt5 import QtCore, QtWidgets
import sys
class MyWidget(QtWidgets.QWidget):
z = 0
def __init__(self, parent):
super().__init__(parent)
self._layout = QtWidgets.QVBoxLayout(self)
def SetData(self):
while self._layout.count() > 0:
widget = self._layout.takeAt(0).widget()
widget.hide()
widget.deleteLater()
for i in range(3):
self._layout.addWidget(QtWidgets.QLabel(str(MyWidget.z * 10 + i)))
MyWidget.z += 1
class CentralWidget(QtWidgets.QWidget):
def __init__(self, parent):
super().__init__(parent)
self._myWidget = MyWidget(self)
# QtWidgets.QHBoxLayout(self).addWidget(self._myWidget)
def SetData(self):
self._myWidget.SetData()
# print("MyWidget\n layout.count: {}\n size: {}\n sizeHint: {}\n\nCentralWidget\n size: {}\n sizeHint: {}\n\n".format(self._myWidget.layout().count(), self.sizeHint(), self.size(), self._myWidget.sizeHint(), self._myWidget.size()))
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
centralWidget = CentralWidget(self)
self.setCentralWidget(centralWidget)
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(centralWidget.SetData)
self._timer.start(500)
def main():
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
app.exec_()
if __name__ == "__main__":
main()
之前调用centralWidget.SetData()
,它将按预期工作。
当您将子窗口小部件添加到布局时,会发生很多事情,这通常涉及多次调用子窗口大小提示,从而允许父窗口调整其自身的大小提示,然后,[[此后,调整其窗口大小提示。大小及其子项。
如果该“容器窗口小部件”本身包含在另一个布局中,则该窗口小部件将在下一个事件周期中自动调整大小(基于其提示),但这在您的情况下不会发生,因为您的容器是“免费的” “小部件。您正在寻找的功能是mainWindow.show()
,但是由于上述原因,您无法在添加子代小部件后立即调用它。要解决您的问题,您可以在QWidget.adjustSize()
之前调用QWidget.adjustSize()
,或者最终使用基于0的单次QTimer: