PySide2 QMainWindow loaded from ui file not triggering window events

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_())

enter image description here

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

Leave a Comment