【问题标题】:PySide2 QMainWindow loaded from ui file not triggering window events从ui文件加载的PySide2 QMainWindow未触发窗口事件
【发布时间】:2019-05-18 14:43:24
【问题描述】:

我正在从 .ui 文件加载 QMainWindow - 它工作正常,但不会触发调整大小等窗口事件。我真的不知道我做错了什么。

这是代码:

class TestWindow(QMainWindow):
    def __init__(self, parent=None):
        super(TestWindow, self).__init__(parent)
        loader = QUiLoader()
        file = QFile(abspath("ui/mainwindow.ui"))
        file.open(QFile.ReadOnly)
        self.window = loader.load(file, parent)
        file.close()
        self.window.show()

    def resizeEvent(self, event):
        print "resize"

app = QApplication(sys.argv)
test = TestWindow()

sys.exit(app.exec_())

.ui 文件可以在here找到。

【问题讨论】:

    标签: python qt-designer pyside2


    【解决方案1】:

    好像你有一个困惑,但是为了你理解调用TestWindow的测试方法:

    import os
    from PySide2 import QtCore, QtWidgets, QtUiTools
    
    class TestWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(TestWindow, self).__init__(parent)
            loader = QtUiTools.QUiLoader()
            file = QtCore.QFile(os.path.abspath("ui/mainwindow.ui"))
            file.open(QtCore.QFile.ReadOnly)
            self.window = loader.load(file, parent)
            file.close()
            self.window.show()
            self.show()
    
        def resizeEvent(self, event):
            print("resize")
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        test = TestWindow()
        sys.exit(app.exec_())
    

    如果你移动小窗口,观察事件是否被触发。

    为什么会这样?:QUiLoader 创建一个基于 .ui 的小部件,与 PyQt5 的 uic.loadUi()ui.loadUiType() 不同,它不会在主小部件中加载而是创建一个新的小部件,也许这是一个缺点,但这就是限制。

    所以根据你想要做什么,有几个选项:

    • 要使用QUiLoader() 加载.ui,不必将TestWindow 作为父级,因为它可以是通过事件过滤器监视事件的QObject

    import os
    from PySide2 import QtCore, QtWidgets, QtUiTools
    
    class Manager(QtCore.QObject):
        def __init__(self, parent_widget=None, parent=None):
            super(Manager, self).__init__(parent)
            loader = QtUiTools.QUiLoader()
            file = QtCore.QFile(os.path.abspath("ui/mainwindow.ui"))
            file.open(QtCore.QFile.ReadOnly)
            self.window = loader.load(file, parent_widget)
            file.close()
            self.window.installEventFilter(self)
            self.window.show()
            self.setParent(self.window)
            self.window.destroyed.connect(lambda *args: print(">>>>>>"))
    
        def eventFilter(self, obj, event):
            if event.type() == QtCore.QEvent.Close and self.window is obj:
                self.window.removeEventFilter(self)
            elif event.type() == QtCore.QEvent.Resize and self.window is obj:
                print("resize")
            return super(Manager, self).eventFilter(obj, event)
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        test = Manager()
        sys.exit(app.exec_())
    
    • 另一种选择是让 self.widow 成为 centralwidget(.ui 中的 QMainWindow 将成为 TestWindow 的 centralwidget,因此调整大小将来自 TestWindow 而不是来自 .ui 而是如同 .ui 的大小一样。 ui 改变了,TestWindow 也一样):

    import os
    from PySide2 import QtCore, QtWidgets, QtUiTools
    
    class TestWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(TestWindow, self).__init__(parent)
            loader = QtUiTools.QUiLoader()
            file = QtCore.QFile(os.path.abspath("ui/mainwindow.ui"))
            if file.open(QtCore.QFile.ReadOnly):
                self.window = loader.load(file, parent)
                file.close()
                self.setCentralWidget(self.window)
                self.show()
    
        def resizeEvent(self, event):
            print("resize")
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        test = TestWindow()
        sys.exit(app.exec_())
    
    • 之前的方法仅用于通知您该事件,但如果您想覆盖,最好使用 pyuic 将 .ui 转换为 .py

    【讨论】:

    • 非常感谢,这确实解决了问题。我不需要覆盖事件。
    猜你喜欢
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 2013-11-23
    • 2015-10-23
    相关资源
    最近更新 更多