TAGS :Viewed: 10 - Published at: a few seconds ago

[ Progress Bar over getOpenFileName ]

In my application I have the following line which opens a file dialog window. Once I get the file name, I do a bunch of processing which takes quite some time, and once this is done the workspace is ready for the user.

filename, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', os.curdir, "*.cws")

The file dialog is a modal window (by default), which is great, because it's preventing the user from doing stupid stuff while the workspace is not ready for use yet. I want to put a progress bar somewhere to give a sense of how much has be processed. I made another dialog window which displays a progress bar and some other information.

Now, since the file dialog window is modal, it just sits there frozen while my workspace is processing, and the progress dialog only pops up after everything is done.

I've looked into setting the file dialog window to not modal, but I don't think that is possible. I was thinking to maybe force it to close, and immediately have my progress dialog window pop up and take over the modality. How can I close the file dialog window programmatically? I don't know how to get a reference for the form.

Or perhaps you have a better suggestion on how to address this?

Answer 1

As thuga mentioned, your application event loop is stuck by your heavy processing. So events (and especialy paint events) are not processed while your processing is running causing the GUI to freeze.

In my opinion, you have 2 options:

Force events to be processesed (not very classy but may work):

It depends on how your "heavy processing" is done. Assuming the code hanging the loop is "under your hands" (not in a third party lib). You can add as much call to QApplication.processEvents as you can in it.

If the processing is loop based, it can look like:

for item in itemList:

This as the main drawback of adding dependencies to GUI in parts of code that should not be aware of. If your code is not loop based then you'll have to add several calls to processEvents that will pollute the processing code.

Stop hanging the event loop (more complicated but more maintainable)

That means you will have to deal with Threads and/or subprocesses as thuga suggested. This solution assumes that GUI code and business code are separated well enough.

You can have a look at this article from Qt Quarterly that gives some highlights on this issue. Because of python Global Interpreter Lock (GIL) you may not see better results with threads. Consider using the multiprocessing library.