从ui文件加载的PySide2 QMainWindow不会触发窗口事件

时间:2018-12-18 08:04:57

标签: python qt-designer pyside2

我正在从.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_())

可以在here中找到.ui文件。

1 个答案:

答案 0 :(得分:0)

您似乎有些困惑,但是为了让您理解,请调用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

如果移动小窗口,请注意事件已触发。

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

因此,根据您要执行的操作,有几种选择:

  • 要使用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