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. 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. So, if I have the setupUi like this:
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. 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). So, if you will need to call show()
on it's own. There are a few ways to proceed from here.
pre
, run
, and post
commands to the dialogAssuming 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_())