PDA

View Full Version : Python QtGui.QFileDialog.getOpenFileName hanging



ChrisOfBristol
17th February 2015, 15:31
I have set up Qt GUI and it all works fine, except when it gets to this bit in my Python program:



newfilename = QtGui.QFileDialog.getOpenFileName(self, 'message', filter = '*.txt')
self.statusBar().showMessage(self.tr('START'))
result = os.system ('sleep 10')
self.statusBar().showMessage(self.tr('END'))


I would expect to choose my file, click open, then the dialogue would disappear and I would see 'START' on the statusbar to reassure me that something good was happening. What happens is that the dialogue sticks with the 'Open' button down until 'sleep 10' has finished, so it looks like the program has hung up. Eventually the dialogue clears, the message 'START' appears momentarily, then 'END'. don't think the dialogue actually does anything to the file like opening or locking it, so it can't be that.

I can upload the whole (very short) test program and .ui file if anyone wants to try it.

d_stranz
18th February 2015, 18:01
Well, no. Qt doesn't do anything GUI-wise until the application has a chance to re-enter the event loop. Modal dialogs implement their own event loops, so that is what is running while the file dialog is open. Only when your code finally exits the routine where the dialog is posted will the events that have stacked up (hiding the dialog, displaying the status messages, etc.) be handled as the app re-enters its event loop. If you do a lot of processing before that occurs (like sleeping for 10 seconds), then you just delay everything further.

If you want the GUI to stay "live", then you need to convert your code into something that is event driven (like emit a signal when the dialog method returns). That puts the app back into the event loop, and the dialog should disappear immediately.

ChrisOfBristol
18th February 2015, 18:55
...and I was hoping for a simple answer:) It's not your fault, it's my lack of knowledge of object orientated/event driven programming, and the fact that this is my first Python program. I think I have a rough idea of what you are saying, so I will spend some time studying it. Thanks for taking the time to explain a complex concept to a beginner. When I've worked out what to do with my program I'll post what I did in case it is of use to another beginner.

ChrisOfBristol
20th February 2015, 17:59
...after some further thought I have understood the first part of your post. I have converted my program to detach a Bash script so it can get on with the processing and the GUI can continue. I decided that was the simplest thing to do considering my limited knowledge of Qt and Python. I also think I see what you mean about signals, I will consider that if I get a similar problem in the future which I can't solve as simply. Thanks.

d_stranz
20th February 2015, 23:27
To put it another way, QCoreApplication (as well as some other Qt objects) run an "event loop". Everything that happens in Qt causes things to be put into stack that is handled in the event loop: UI actions (like mouse clicks, key presses, etc.), timer timeouts, file and network operations, and so forth. In order for the even loop to remain active (that is, processing the events that have been pushed onto the stack), the application needs to run the code that processes these events.

If you do something compute intensive (like compute all the prime numbers less than infinity) and you don't exit that routine until it's done, then you have effectively blocked Qt from running the event loop and your application GUI will be dead for all intents and purposes.

There are (at least) three ways around this:

1 - In the loop that does the compute-intensive operation, insert a call to QCoreApplication::processEvents()
2 - Convert the computation into something that is event driven instead, using signals and slots
3 - Run the computation in a separate thread, and optionally communicate with the main GUI using signals and slots.

I am only learning Python myself, but Python is no different from C++ when it comes to what Qt is doing under the hood.

ChrisOfBristol
26th February 2015, 23:46
Thanks again for explaining this further, one of these options would enable me to write an improved version 2 of my app.