隐藏小部件后调用size()时,应用大小不会更改

时间:2019-05-16 04:55:47

标签: python pyqt pyqt5

在隐藏小部件并将其sizePolicy设置为“忽略”后,我试图将我的应用调整为较小的尺寸。但是,该应用程序的大小不会像以前一样缩小,就像隐藏的小部件仍在占用空间一样。

在隐藏第二个小部件/将其sizePolicy设置为Ignored之后,并尝试调整应用程序的大小之后,我尝试过包含self.update()self.updateGeometry()app.processEvents(),但它们似乎都没有产生任何效果。

class App(QWidget):
    def __init__(self):
        super().__init__()

        # basic setup
        self.move(100, 100)

        # main widgets
        self.advanced_metadata = QCheckBox("Advanced", self)
        self.advanced_metadata.stateChanged.connect(self.displayAdvanced)
        self.first_widget = QLabel('first_widget', self)
        self.second_widget = QLabel('second_widget', self)
        self.second_widget.setHidden(True)
        self.second_widget.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)

        # main layout
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.advanced_metadata)
        self.layout().addWidget(self.first_widget)
        self.layout().addWidget(self.second_widget)
        self.layout().addStretch()

        self.resizeApp(650, self.sizeHint().height())

        self.show()

    # toggles advanced metadata view
    def displayAdvanced(self):
        if self.advanced_metadata.isChecked():
            self.second_widget.setVisible(True)
            self.second_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

            self.resizeApp(650, self.sizeHint().height())

        else:
            self.second_widget.setHidden(True)
            self.second_widget.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)

            self.resizeApp(650, self.sizeHint().height())

    # resizes main window
    def resizeApp(self, width, height):
        self.resize(width, height)
        print(self.size())

if __name__ == '__main__':
    # accounts for exiting errors in python
    if not QApplication.instance():
        app = QApplication(sys.argv)
    else:
        app = QApplication.instance()
    ex = App()
    app.exec_()

我希望窗口的大小在初始化时为650x112,然后在选中Advanced复选框时,尺寸应更改为650x149,最后,当未选中Advanced复选框时,尺寸应该恢复为650x112。最后的期望没有发生。而是将窗口保持在650x149。

1 个答案:

答案 0 :(得分:1)

在Qt中,许多任务是异步完成的,这就是几何形状的情况,因此,即使您更改了策略,这也不会立即应用,直到同步部分结束。因此,一种解决方法是稍后使用QTimer.singleShot(0, ...)来应用调整大小。

from functools import partial
from PyQt5 import QtCore, QtWidgets


class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.move(100, 100)
        # main widgets
        self.advanced_metadata = QtWidgets.QCheckBox(
            "Advanced", stateChanged=self.displayAdvanced
        )
        self.first_widget = QtWidgets.QLabel("first_widget")
        self.second_widget = QtWidgets.QLabel("second_widget")
        self.second_widget.setHidden(True)
        self.second_widget.setSizePolicy(
            QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored
        )
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.advanced_metadata)
        lay.addWidget(self.first_widget)
        lay.addWidget(self.second_widget)
        lay.addStretch()

        self.resizeApp(650, self.sizeHint().height())

    # toggles advanced metadata view
    @QtCore.pyqtSlot(int)
    def displayAdvanced(self, state):
        if state == QtCore.Qt.Checked:
            self.second_widget.show()
            self.second_widget.setSizePolicy(
                QtWidgets.QSizePolicy.Preferred,
                QtWidgets.QSizePolicy.Preferred,
            )

        else:
            self.second_widget.hide()
            self.second_widget.setSizePolicy(
                QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored
            )
        wrapper = partial(self.resizeApp, 650, self.sizeHint().height())
        QtCore.QTimer.singleShot(0, wrapper)

    @QtCore.pyqtSlot(int, int)
    def resizeApp(self, width, height):
        self.resize(width, height)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())