PySide QTabWidget 中选项卡的触发关闭事件

Trigger Close Event for Tabs in PySide QTabWidget

我写了 3 个独立的小部件,每个小部件都包含一个 'closeEvent'。但是,当小部件作为选项卡放置在 MainWindow 中时,不会触发关闭事件。当 MainWindow 关闭时,如何发出信号以正确触发每个选项卡的 'closeEvent'?

我已尽力简化代码以专注于主要目标。我想为每个选项卡发出关闭事件,这样将来当我添加更多选项卡时它会更加灵活并且每个工具仍然是独立的。

import sys
from PySide import QtGui, QtCore

class TabA(QtGui.QWidget):
    def __init__(self, parent=None):
        super(TabA, self).__init__(parent)
        self.resize(300, 300)
        self.setWindowTitle('App A')
        self.btn = QtGui.QPushButton("Button A")
        grid = QtGui.QGridLayout()
        grid.addWidget(self.btn)
        self.setLayout(grid)

    def closeEvent(self, event):
        print "closing Tab A"
        event.accept()

class TabB(QtGui.QWidget):
    def __init__(self, parent=None):
        super(TabB, self).__init__(parent)
        self.resize(300, 300)
        self.setWindowTitle('App A')
        self.btn = QtGui.QPushButton("Button A")
        grid = QtGui.QGridLayout()
        grid.addWidget(self.btn)
        self.setLayout(grid)

    def closeEvent(self, event):
        print "closing Tab A"
        event.accept()

class TabC(QtGui.QWidget):
    def __init__(self, parent=None):
        super(TabC, self).__init__(parent)
        self.resize(300, 300)
        self.setWindowTitle('App A')
        self.btn = QtGui.QPushButton("Button A")
        grid = QtGui.QGridLayout()
        grid.addWidget(self.btn)
        self.setLayout(grid)

    def closeEvent(self, event):
        print "closing Tab A"
        event.accept()

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.initUI()

    def initUI(self):
        self.resize(300, 300)
        self.setWindowTitle('Tabs')

        # Tabs
        main_tabWidget = QtGui.QTabWidget()
        main_tabWidget.addTab(TabA(), "TabA")
        main_tabWidget.addTab(TabB(), "TabB")
        main_tabWidget.addTab(TabC(), "TabC")

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(main_tabWidget)
        vbox.setContentsMargins(0, 0, 0, 0)

        main_widget = QtGui.QWidget()
        main_widget.setLayout(vbox)
        self.setCentralWidget(main_widget)


def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

closeEvent 方法仅在收到关闭请求时为顶级 window 调用,因此它不适合您的用例。但是,当应用程序关闭时会发出几个信号,您可以连接到这些信号。

例如,您可以这样做:

class TabA(QtGui.QWidget):
    def __init__(self, parent=None):
        super(TabA, self).__init__(parent)
        ...
        QtGui.qApp.aboutToQuit.connect(self.handleClose)

    def handleClose(self):
        print "closing Tab A"

这个信号是在事件循环退出之前发出的,还有一个 QtGui.qApp.lastWindowClosed 信号是在主 window 关闭之后发出的。

(PS:不要试图为此目的使用 __del__,因为关闭期间的确切行为在 PyQt 中是严格未定义的,并且可以在版本之间更改)。