PySide2 QMainWindow loaded from ui file not triggering window events

前端 未结 1 1185
遥遥无期
遥遥无期 2021-01-23 20:21

I am loading a QMainWindow from an .ui file - it\'s working fine but window events like resize won\'t be triggered. I can\'t really figure out what I am doing wrong.

Thi

相关标签:
1条回答
  • 2021-01-23 20:47

    It seems that you have a confusion, but for you to understand call the test method of 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_())
    

    And if you move the small window observe that the event is triggered.

    Why does that happen?: QUiLoader creates a widget based on the .ui that unlike uic.loadUi() or ui.loadUiType() of PyQt5 does not load in the main widget but creates a new widget, maybe that's a disadvantage but that's the limitations.

    So depending on what you want to do there are several options:

    • To load the .ui with QUiLoader() it is not necessary to have TestWindow as a parent since it can be a QObject that monitors the events through an event filter.

    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_())
    
    • Another option is to make the self.widow the centralwidget (the QMainWindow in the .ui will be the centralwidget of the TestWindow, so the resize will be from the TestWindow not from the .ui but as if the size of the .ui is changed, the same will happen with 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_())
    
    • The previous methods only serve to notify you of the event but if you want to overwrite it is better that you use pyuic converting the .ui to .py
    0 讨论(0)
提交回复
热议问题