简体   繁体   English

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

[英]PySide2 QMainWindow loaded from ui file not triggering window events

I am loading a QMainWindow from an .ui file - it's working fine but window events like resize won't be triggered.我正在从 .ui 文件加载 QMainWindow - 它工作正常,但不会触发像调整大小这样的窗口事件。 I can't really figure out what I am doing wrong.我真的无法弄清楚我做错了什么。

This is the code:这是代码:

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

The .ui file can be found here . .ui 文件可以在这里找到。

It seems that you have a confusion, but for you to understand call the test method of TestWindow:看来你有一个困惑,但为了你理解调用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. : QUiLoader 基于 .ui 创建一个小部件,与uic.loadUi()ui.loadUiType() ,它不会在主小部件中加载而是创建一个新的小部件,这可能是一个缺点,但这就是限制。

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.要使用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_())
  • 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):另一种选择是使 self.widow 成为 centralwidget(.ui 中的 QMainWindow 将是 TestWindow 的 centralwidget,因此调整大小将来自 TestWindow 而不是来自 .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_())
  • 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以前的方法仅用于通知您该事件,但如果您想覆盖,最好使用 pyuic 将 .ui 转换为 .py

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM