Pyside uiLoader捕获关闭事件信号

时间:2018-10-10 19:10:26

标签: python pyside

如何正确捕获PySide QtUiTools.QUiLoader()设置发出的关闭事件?

我可以让实例化的类连接到小部件以及其他所有东西,但是我不确定如何在此设置中拦截信号。

理想情况下,我希望所有close调用都通过我的closeEvent传递(显然),以便可以确保安全关闭窗口。但是由于我的self.closeEvent()绑定到了View(QtWidgets.QMainWindow)而不是self._qt.closeEvent()上,所以我不知道如何使用self._qt.closeEvent()方法来覆盖它在这种情况下。

还是有更好的方法来设置它以捕获那些窗口事件?

# Compatible enough with Pyside 2
from PySide import QtGui as QtWidgets
from PySide import QtUiTools
from PySide import QtCore

class View(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(View, self).__init__(parent=parent)
        self.setup()

    def closeEvent(self, event):

        # Do things
        event.accept()

    def setup(self):
        loader = QtUiTools.QUiLoader()
        fy = QtCore.QFile('example.ui')
        fy.open(QtCore.QFile.ReadOnly)
        self._qt = loader.load(fy, self)
        fy.close()

        self._qt.pCanceled.clicked(self._qt.close)

不适用:

PySide / PyQt detect if user trying to close window

关闭,但是PySide不使用PyQt的uic,并且运行方式不同(并且不起作用):

PyQt: clicking X doesn't trigger closeEvent

1 个答案:

答案 0 :(得分:1)

closeEvent不是信号,它是发送QCloseEvent事件时调用的方法。信号和事件是不同的东西。问题在于,在Qt中,有两种监听事件的方法,第一种是覆盖fooEvent()方法,第二种是使用事件过滤器,如下所示:

from PySide import QtGui as QtWidgets
from PySide import QtUiTools
from PySide import QtCore

class View(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(View, self).__init__(parent=parent)
        self._qt = None
        self.setup()

    def closeEvent(self, event):
        self.do_things()
        super(View, self).closeEvent(event)

    def do_things(self):
        print("do_things")

    def setup(self):
        loader = QtUiTools.QUiLoader()
        fy = QtCore.QFile('example.ui')
        fy.open(QtCore.QFile.ReadOnly)
        self._qt = loader.load(fy, self)
        fy.close()
        self._qt.pCanceled.clicked.connect(self._qt.close)
        self._qt.installEventFilter(self)

    def eventFilter(self, watched, event):
        if watched is self._qt and event.type() == QtCore.QEvent.Close:
            self.do_things()
        return super(View, self).eventFilter(watched, event)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = View()
    w.show()
    sys.exit(app.exec_())

更新

通常在eventFilter中,返回True就足以忽略该事件,但是对于QCloseEvent,您必须忽略该事件并返回True,如下所示:

def eventFilter(self, watched, event):
    if watched is self._qt and event.type() == QtCore.QEvent.Close:
        self.do_things()
        event.ignore()
        return True
    return super(View, self).eventFilter(watched, event)