使用QUiLoader()加载MainWindow时如何接受关闭事件?

问题描述 投票:0回答:2

下面的代码如何接收关闭事件?

class Main(QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.view = QUiLoader().load("sample.ui", self)
        self.view.show()

    def closeEvent(self, e):
        print "close event recieved"

def main():
    app = QApplication(sys.argv)
    a=Main()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

如果我使用 pyside-uic 将sample.ui 转换为sample.py 并将其导入到main.py 中,那么我就能够接收关闭事件。

from sample import Ui_MainWindow

class Main(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.setupUi(self)

    def closeEvent(self, e):
        print "close event recieved"

app = QApplication(sys.argv)
a=Main()
a.show()
sys.exit(app.exec_())
python qt pyside
2个回答
4
投票

第二个示例之所以有效,是因为它实际上成为 Qt Designer 顶级类的子类。相比之下,第一个示例使用组合而不是子类化,它将所有 gui 元素放入内部命名空间内。

Main
类只是一个容器,充当
view
小部件的父级,并且从未实际显示(这又意味着它不会接收任何关闭事件)。

在 PyQt 中,

uic
模块有几个功能可以让您解决这些问题,但目前 PySide 中没有类似的功能。相反,您必须推出自己的函数。有关如何执行此操作的说明,请参阅此答案

或者,您可以将 Qt Designer 中的顶级类更改为

QWidget
,然后使
view
成为
Main
类的中心小部件。不过,这比上面的方法灵活性差很多。


0
投票

我喜欢这个修复,它很丑,但比其他的更丑,更短(对于 PySide2):

w = QuiLoader().load('myui.ui'), None)  # create a QMainWindow with broken closeEvent

ww = QMainWindow()  # create a nice QMainWindow
ww.setLayout(QVBoxLayout())
ww.layout().addWidget(w)  # just put it inside

ww.closeEvent = lambda e: print('CLOSE!')  # woohoo!
© www.soinside.com 2019 - 2024. All rights reserved.