PyQT4:当setVisible(false)时,为什么QDialog从exec_u()返回

2024-06-29 01:09:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是python2.7和PyQT4。在

我想隐藏一个模态QDialog实例,稍后再显示它。但是,什么时候对话框.setVisible(false)被调用(例如,使用QTimer),则对话框.exec_()呼叫返回(带QDialog.已拒绝返回值)。在

但是,根据http://pyqt.sourceforge.net/Docs/PyQt4/qdialog.html#exec,在用户关闭对话框之前,\u exec()调用应该被阻塞。在

有没有一种方法可以在不返回的情况下隐藏对话框?在

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
from PyQt4 import QtGui, QtCore


class MyDialog(QtGui.QDialog):
    def __init__(self, parent):
        QtGui.QDialog.__init__(self, parent)

    def closeEvent(self, QCloseEvent):
        print "Close Event"

    def hideEvent(self, QHideEvent):
        print "Hide Event"


class MyWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle("Main Window")
        button = QtGui.QPushButton("Press me", self)
        button.clicked.connect(self.run_dialog)

    def run_dialog(self):
        self.dialog = MyDialog(self)
        self.dialog.setModal(True)
        self.dialog.show()
        QtCore.QTimer.singleShot(1000, self.hide_dialog)
        status = self.dialog.exec_()
        print "Dialog exited with status {}".format(status), "::", QtGui.QDialog.Accepted, QtGui.QDialog.Rejected

    def hide_dialog(self):
        self.dialog.setVisible(False)
        # self.dialog.setHidden(True)


if __name__ == '__main__':
    app = QtGui.QApplication([])
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

PS1:此代码打印以下输出:

^{pr2}$

(不调用关闭事件)。在

PS2:对于上下文,我试图实现一个SystemTrayIcon,它允许在不关闭对话框的情况下隐藏和恢复QMainWindow(这个部分很好)和可能的模态QDialog。在

谢谢!在


Tags: importselfinitdefstatusdialog对话框exec
2条回答

如果有人感兴趣,下面的代码为我提供了一种快速而肮脏的方法来解决问题,尽管它并不能真正回答问题。在

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Extension of the QDialog class so that exec_() does not exit when hidden.

Dialogs inheriting will only exit exec_() via close(), reject() or accept()
"""

from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class HideableQDialog(QDialog):
    def __init__(self, *args, **kwargs):
        super(HideableQDialog, self).__init__(*args, **kwargs)
        self._mutex = QMutex()
        self._is_finished = False
        self._finished_condition = QWaitCondition()
        self.finished.connect(self._finish_dialog)

    def _finish_dialog(self):
        self._is_finished = True
        self._finished_condition.wakeOne()

    def close(self):
        super(HideableQDialog, self).close()
        self._finish_dialog()

    def reject(self):
        super(HideableQDialog, self).reject()
        self._finish_dialog()

    def accept(self):
        super(HideableQDialog, self).accept()
        self._finish_dialog()

    def exec_(self):
        status = super(HideableQDialog, self).exec_()
        self._mutex.lock()
        condition_succedeed = False
        while not condition_succedeed and not self._is_finished:
            condition_succedeed = self._finished_condition.wait(self._mutex, 10)
            QApplication.processEvents()
        self._mutex.unlock()

您可以通过调用基类方法来绕过QDialog.setVisible(它隐式关闭对话框)的正常行为:

    def hide_dialog(self):
        # self.dialog.setVisible(False)
        QtGui.QWidget.setVisible(self.dialog, False)

但是,最好连接到对话框的finished()信号,而不是使用exec(),并在其closeEvent中显式地reject()对话框。在

^{pr2}$

相关问题 更多 >