Xiidozen
Xiidozen

Reputation: 93

PyQt QFileDialog does not close when using native dialog

I am using PyQt to get a filename form the user. I have developed a minimum example to show the issue. If I use the static function QFileDialog.getOpenFileName, and I pass the QFileDialog.DontUseNativeDialog, the file dialog behaves as expected. If I do not provide that option, the dialog will not close when the user selects a file. The dialog only closes after the script completes execution.

import sys
import time
from PyQt4.QtGui import *
a = QApplication(sys.argv) 
filename = QFileDialog.getOpenFileName(None, 'Open File', '.', '*',    '*', QFileDialog.DontUseNativeDialog) #works
#filename = QFileDialog.getOpenFileName(None, 'Open File', '.', '*', '*') #doesn't work
a.quit()
a = None
print filename
print "Dialog should be gone"
time.sleep(10)

When the user selects a file, if "DontUseNativeDialog" is not used, the dialog will stay up until after the 10 second sleep. I'd expect the dialog to close as soon as the user clicks OK or Cancel.

Upvotes: 1

Views: 2225

Answers (1)

furas
furas

Reputation: 143187

Most GUI needs mainloop (event loop) which runs all time and makes all job in GUI.

You can use a.exec_() to start mainloop in PyQt and it closes dialog but then you will have problem how to stop this mainloop :)

a.quit() can close it but if you use it before a.exec_() then mainloop doesn't receive this message and doesn't close. If you put after a.exec_() then it will be never executed because a.exec_() blocks all code till you ends mainloop. But you can use QTimer with a.quit to inform mainloop to execute it after it will be started.

import sys
import time
from PyQt4.QtGui import *
from PyQt4.QtCore import QTimer

a = QApplication(sys.argv) 

#filename = QFileDialog.getOpenFileName(None, 'Open File', '.', '*',    '*', QFileDialog.DontUseNativeDialog) #works
filename = QFileDialog.getOpenFileName(None, 'Open File', '.', '*', '*') #doesn't work

# run a.quit after 100ms
QTimer.singleShot(100, a.quit)
# run mainloop
a.exec_()

print(filename)
print "Dialog should be gone"
time.sleep(10)

Upvotes: 3

Related Questions