接受不重绘后,QDialog切换到非模态

时间:2013-09-14 18:42:04

标签: python pyqt redraw qdialog non-modal

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

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_()

现在,我遇到的问题是,我有一个Command创建一个对话框,并等待用户接受它。然后,我需要在命令运行时将对话框切换到非模态,并在对话框中更新日期。这一切似乎都很好。但是,问题是我无法在pre,run和post方法完成之前重新绘制对话框。所以,如果我有这样的setupUi:

def setupUi(self):
    # create a ui for this command
    diag = QDialog()
    if diag.exec_():
        diag.setModal(False)
        diag.show()

我尝试过processEvents但似乎没有这样做。还有其他人遇到过这个问题,或者知道有什么工作吗?

由于

1 个答案:

答案 0 :(得分:0)

使用diag.exec_()将阻止,直到对话框返回(关闭)。所以,如果您需要自己调用show()。有几种方法可以从这里开始。

  1. 您可以让对话框接受槽运行对其余命令的引用
  2. 您可以轮询对话框以查看用户是否已接受
  3. 您可以将prerunpost命令移至对话框
  4. 假设您希望将代码的内容保留在对话框类之外,并且由于定期轮询最好尽可能避免,这是第一个策略的示例:

    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_())