Python QDialog在接受不重画后切换到非模态

Python QDialog在接受不重画后切换到非模态,python,pyqt,redraw,qdialog,non-modal,Python,Pyqt,Redraw,Qdialog,Non Modal,所以,我不确定标题是否是最好的描述,但这是我想到的。 事情是这样的。我正在开发一个PyQt应用程序,它有一种插件系统,你只需在文件夹中添加一些子类,应用程序就会找到它们。这些命令可以选择为自己创建小UI。基本上,它们看起来是这样的: class Command(object): def do(self): self.setupUi() self.pre() self.run() self.post() def pr

所以,我不确定标题是否是最好的描述,但这是我想到的。 事情是这样的。我正在开发一个PyQt应用程序,它有一种插件系统,你只需在文件夹中添加一些子类,应用程序就会找到它们。这些命令可以选择为自己创建小UI。基本上,它们看起来是这样的:

class Command(object):
    def do(self):
        self.setupUi()
        self.pre()
        self.run()
        self.post()

    def pre(self):
        # do setup stuff for run method

    def run(self):
        # do actual work

    def post(self):
        # clean up after run

    def setupUi(self):
        # create a ui for this command
        diag = QDialog()
        diag.exec_()
def setupUi(self):
    # create a ui for this command
    diag = QDialog()
    if diag.exec_():
        diag.setModal(False)
        diag.show()
现在,我遇到的问题是,我有一个命令创建一个对话框,并等待用户接受它。然后,我需要在命令运行时将对话框切换为非模态,并更新对话框。这一切似乎都很好。但是,问题是在pre、run和post方法完成之前,我无法让对话框重新绘制。因此,如果我有这样的setupUi:

class Command(object):
    def do(self):
        self.setupUi()
        self.pre()
        self.run()
        self.post()

    def pre(self):
        # do setup stuff for run method

    def run(self):
        # do actual work

    def post(self):
        # clean up after run

    def setupUi(self):
        # create a ui for this command
        diag = QDialog()
        diag.exec_()
def setupUi(self):
    # create a ui for this command
    diag = QDialog()
    if diag.exec_():
        diag.setModal(False)
        diag.show()
我尝试了processEvents,但似乎没有成功。有没有其他人遇到过这个问题,或者知道任何解决方法

谢谢

使用diag.exec将被阻止,直到对话框关闭。所以,如果你需要自己给show打电话。有几种方法可以从这里开始

您可以让对话框accept slot运行对其余命令的引用 您可以轮询对话框以查看用户是否已接受 可以将pre、run和post命令移动到对话框中 假设您希望将代码的主要部分排除在dialog类之外,并且如果可能,最好避免定期轮询,下面是第一种策略的示例:

import sys, time

from PyQt4 import QtCore, QtGui

class MyDialog(QtGui.QDialog):
    def __init__(self,parent=None):
        QtGui.QDialog.__init__(self,parent)
        layout = QtGui.QVBoxLayout()
        self.msg = QtGui.QLabel('some sort of status')
        self.buttonbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok, QtCore.Qt.Horizontal, self)
        self.buttonbox.accepted.connect(self.accept)
        layout.addWidget(self.msg)
        layout.addWidget(self.buttonbox)
        self.setLayout(layout)

    def set_msg(self, new_msg):
        self.msg.setText(new_msg)

    def set_function_on_accept(self,fcn):
        self.function = fcn

    def accept(self):
        self.function()


class Command(object):
    def do(self):
        self.setupUi()

    def do_work(self):
        self.pre()
        self.run()
        self.post()

    def pre(self):
        # do setup stuff for run method
        time.sleep(1)
        self.diag.set_msg("stuff setup")
        QtGui.QApplication.processEvents()

    def run(self):
        # do actual work
        time.sleep(1)
        self.diag.set_msg("work done")
        QtGui.QApplication.processEvents()

    def post(self):
        # clean up after run
        time.sleep(1)
        self.diag.set_msg("cleaned up")
        QtGui.QApplication.processEvents()

    def setupUi(self):
        # create a ui for this command
        diag = MyDialog()
        self.diag = diag
        diag.set_function_on_accept(self.do_work)
        diag.show()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    command = Command()
    command.do()
    sys.exit(app.exec_())