【问题标题】:App size doesn't change when size() is called after hiding widgets隐藏小部件后调用 size() 时应用程序大小不会改变
【发布时间】:2019-10-03 06:58:41
【问题描述】:

在隐藏小部件并将其 sizePolicy 设置为 Ignored 后,我正在尝试将我的应用程序调整为更小的尺寸。但是,应用程序不会调整到比以前更小的大小,就好像隐藏的小部件仍然在那里占用空间一样。

在隐藏第二个小部件/将其 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_()

I expect the size of the window when initialized to be 650x112, then when the Advanced checkbox is selected the size should change to 650x149, and lastly, when the Advanced checkbox is unchecked, the size should revert back to 650x112。最后的期望没有发生;相反,窗口仍为 650x149。

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案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_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多