从 ui 文件加载的 PySide2 QMainWindow 不触发窗口事件 [英] PySide2 QMainWindow loaded from ui file not triggering window events

查看:93
本文介绍了从 ui 文件加载的 PySide2 QMainWindow 不触发窗口事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是代码:

class TestWindow(QMainWindow):def __init__(self, parent=None):super(TestWindow, self).__init__(parent)加载器 = QUiLoader()file = QFile(abspath("ui/mainwindow.ui"))file.open(QFile.ReadOnly)self.window = loader.load(file, parent)文件.close()self.window.show()def resizeEvent(self, event):打印调整大小"app = QApplication(sys.argv)测试 = 测试窗口()sys.exit(app.exec_())

可以在

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

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

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

  • 要使用 QUiLoader() 加载 .ui,不必将 TestWindow 作为父项,因为它可以是一个 QObject通过事件过滤器监控事件.
<小时>

导入操作系统从 PySide2 导入 QtCore、QtWidgets、QtUiTools类管理器(QtCore.QObject):def __init__(self, parent_widget=None, parent=None):超级(经理,自我).__init__(父母)loader = QtUiTools.QUiLoader()file = QtCore.QFile(os.path.abspath("ui/mainwindow.ui"))file.open(QtCore.QFile.ReadOnly)self.window = loader.load(file, parent_widget)文件.close()self.window.installEventFilter(self)self.window.show()self.setParent(self.window)self.window.destroyed.connect(lambda *args: print(">>>>>>"))def eventFilter(self, obj, event):如果 event.type() == QtCore.QEvent.Close 并且 self.window 是 obj:self.window.removeEventFilter(self)elif event.type() == QtCore.QEvent.Resize 和 self.window 是 obj:打印(调整大小")return super(Manager, self).eventFilter(obj, event)如果 __name__ == '__main__':导入系统app = QtWidgets.QApplication(sys.argv)测试 = 经理()sys.exit(app.exec_())

  • 另一种选择是使 self.widow 成为 centralwidget(.ui 中的 QMainWindow 将是 TestWindow 的 centralwidget,因此调整大小将来自 TestWindow 而不是来自 .ui 而是好像 .ui 文件的大小.ui 已更改,TestWindow 也会发生相同的情况):
<小时>

导入操作系统从 PySide2 导入 QtCore、QtWidgets、QtUiTools类测试窗口(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)文件.close()self.setCentralWidget(self.window)自我展示()def resizeEvent(self, event):打印(调整大小")如果 __name__ == '__main__':导入系统app = QtWidgets.QApplication(sys.argv)测试 = 测试窗口()sys.exit(app.exec_())

  • 之前的方法仅用于通知您事件,但如果您想覆盖,最好使用 pyuic 将 .ui 转换为 .py

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.

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.

解决方案

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

这篇关于从 ui 文件加载的 PySide2 QMainWindow 不触发窗口事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆