5

QVBoxLayout他の複数のウィジェットを含むを作成しました。QVBoxLayout(現在 a )の親ウィンドウQDialogが閉じられると、一時ファイルを削除できるように、すべてのウィジェットに close イベントを通知する必要があります。これは慣用的で、どうすればそれを行うことができますか?

私のアプリケーションでは、QLabelpixMap を構成する一時ファイルへの参照を格納できるクラスでサブクラス化しました。親ウィンドウが閉じられたら、ファイルを閉じることができる必要があります。

編集:私はすでに閉じるイベントを処理しようとしました:

def closeEvent(self, event):
    self.imgFile.close()
4

1 に答える 1

3

慣用的な Qt と思われるものを使用して、これを達成できるいくつかの方法を次に示します。

  1. 親で を使用しcloseEventて、各子でクリーンアップを直接実行します。
  2. destroyed親のシグナルを使用して、各子で間接的にクリーンアップを呼び出します
  3. 親の からカスタム シグナルを発信しcloseEvent、子のクリーンアップに直接接続します。

オプション #2/#3 は、次のようにコメントアウトされています。

from PyQt4 import QtCore, QtGui


class MainWidget(QtGui.QDialog):

    # Option #3 - Custom signal
    closing = QtCore.pyqtSignal()

    def __init__(self):
        super(MainWidget, self).__init__()

        self.layout = QtGui.QVBoxLayout(self)

        for i in xrange(5):
            label = ResourceLabel('label%02d' % i)
            self.layout.addWidget(label)

            # option #2
            # Let a signal trigger the cleanup on the children
            # self.destroyed.connect(label.close)

            # option #3
            # Use a custom signal emitted from the closeEvent,
            # wired directly to the cleanup slot on the object
            # self.closing.connect(label.close)

    def closeEvent(self, event):
        print "Closing main window"

        # option #1
        # if you want to trigger a cleanup specifically when
        # this widget is closed, as opposed to destroyed
        for i in xrange(self.layout.count()):
            item = self.layout.itemAt(i)
            widget = item.widget()       
            if widget:
                try:
                    widget.close()
                except:
                    pass

        # Or Option #3 - emit a custom signal
        self.closing.emit()

        super(MainWidget, self).closeEvent(event)


class ResourceLabel(QtGui.QLabel):

    def __init__(self, *args, **kwargs):
        super(ResourceLabel, self).__init__(*args, **kwargs)
        self.aResource = "FOO"

    def close(self):
        print "Cleaning up", self
        self.aResource = None


if __name__ == "__main__":
    app = QtGui.QApplication([])
    win = MainWidget()
    win.show()
    win.raise_()
    app.exec_()

どちらでも動作します。オプション #2 の方が気に入っています。これは、親ウィンドウがその子に少し依存せず、構築時に適切なウィンドウをクリーンアップするスロットに接続するだけだからです。

オプション #3 の理由は、以下のコメントに基づいています。あなたが投稿したコードでは、あなたのダイアログは実際にはまったく削除されていないと思います。それはまだ存在し、閉鎖されたばかりです。したがって、閉じるイベントはトリガーされますが、破棄シグナルはトリガーされません。したがって、オプション 3 は、カスタム シグナルを closeEvent に配置します。これは、destroyedシグナルが削除された場合にシグナルが行う動作を正確に模倣します。

于 2012-12-24T05:16:00.077 に答える