简体   繁体   English

接受不重画后,QDialog切换到非模式

[英]QDialog switch to non-modal after accept not redrawing

So, I'm not sure if the title is the best description, but it's what I came up with. 因此,我不确定标题是否是最好的描述,但这就是我想出的。 Here's the deal. 这是交易。 I'm working on a PyQt app that has a sort of plugin system where you can just add some sub classes to a folder and the app finds them. 我正在开发一种PyQt应用,该应用具有某种插件系统,您可以在其中将一些子类添加到文件夹中,然后该应用会找到它们。 These commands have the option of being able to create little uis for themselves. 这些命令可以选择自己创建一些用户界面。 Basically, they look like this: 基本上,它们看起来像这样:

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

Now, the issue I'm running into is, I have one Command that creates a dialog, and waits for the user to accept it. 现在,我遇到的问题是,我有一个命令可以创建一个对话框,并等待用户接受它。 Then, I need to switch the dialog to non-modal while the command is running, and up date the dialog. 然后,我需要在命令运行时将对话框切换为非模式对话框,并更新对话框。 This all seems to work fine. 这一切似乎都很好。 But, the problem is I can't get the dialog to redraw until after the pre, run, and post methods have finished. 但是,问题是,直到pre,run和post方法完成后,我才能重绘对话框。 So, if I have the setupUi like this: 所以,如果我有这样的setupUi:

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

I tried processEvents but that didn't seem to do it. 我尝试了processEvents,但似乎没有做到。 Has anyone else run into this issue, or know of any work arounds? 是否还有其他人遇到此问题,或者是否有任何解决方法?

Thanks 谢谢

Using diag.exec_() will block until the dialog returns (is closed). 使用diag.exec_()将阻塞,直到对话框返回(关闭)。 So, if you will need to call show() on it's own. 因此,如果您需要自己调用show() There are a few ways to proceed from here. 从这里开始有几种方法。

  1. You can have the dialog accept slot run a reference to the rest of the commands 您可以让对话框接受插槽运行对其余命令的引用
  2. You can poll the dialog to see if the user has accepted 您可以轮询对话框以查看用户是否已接受
  3. You can move the pre , run , and post commands to the dialog 您可以将prerunpost命令移至对话框

Assuming you want to keep the meat of the code out of the dialog class, and since periodically polling is best to avoid if possible, here is an example of the first strategy: 假设您希望将代码的内容排除在对话框类之外,并且由于最好避免定期轮询,因此以下是第一种策略的示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM