Dans mon application PyGTK, je demande à un utilisateur de trouver un fichier afin que des opérations puissent y être effectuées. L'application demande à l'utilisateur le fichier et relaie ce nom de fichier aux méthodes nécessaires. Malheureusement, lorsque vous appelez la méthode gtk.dispose()
dans cette boîte de dialogue, elle reste bloquée jusqu'à ce que la méthode appelée pour exécuter le fichier-IO soit terminée. J'ai même essayé de placer les manipulations de fichier à l'intérieur d'un autre thread, mais cela n'a eu aucun effet.PyGTK Fenêtre ne se cachant pas quand on lui dit
Mon but indenté est que le programme affiche une boîte de dialogue à l'utilisateur pour l'informer que le fichier qu'il a sélectionné pour la manipulation a lieu. Avec la mise en œuvre actuelle, la boîte de dialogue apparaît après le gtk.FileChooserDialog
est disposé.
est mon code ci-dessous:
def performFileManipulation(self, widget, data=None):
# Create the file chooser dialog:
dialog = gtk.FileChooserDialog("Open..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
# Display the file selector and obtain the response back
response = dialog.run()
# If the user selected a file, then get the filename:
if response == gtk.RESPONSE_OK:
dataLocation = dialog.get_filename()
# If the file was not chosen, then just close the window:
else:
print "Closed, no files selected" # Just for now
########## Problem Area ##########
# The dialog is told to get destroyed, however, it hangs here in an
# unresponsive state until the the file-manipulations performed in a new thread
# below are completed. Then, the status dialog (declared below) is displayed.
dialog.destroy() # Close the dialog.
## Show a dialog informing the user that the file manipulation is taking place:
statusDialog = gtk.Dialog("Performing File Operations...", parent=None, flags=0, buttons=None)
statusLabel = gtk.Label("Performing File Operations.\nPlease wait...")
statusLabel.set_justify(gtk.JUSTIFY_CENTER)
statusLabel.show()
statusDialog.vbox.pack_start(statusLabel, True, True, 0)
statusDialog.set_default_size(350, 150)
statusDialog.show()
# Create the thread to perform the file conversion:
errorBucket = Queue.Queue() # Make a bucket to catch all errors that may occur:
theFileOperationThread = doStuffToTheFile(dataLocation, errorBucket) # Declare the thread object.
## Perform the file operations:
theFileOperationThread.start() # Begin the thread
# Check on the thread. See if it's still running:
while True:
theFileOperationThread.join(0.1)
if theFileOperationThread.isAlive():
continue
else:
break
# Check if there was an error in the bucket:
try:
errorFound = errorBucket.get(False)
# If no errors were found, then the copy was successful!
except Queue.Empty:
pass
# There was an error in the bucket! Alert the user
else:
print errorFound
statusDialog.destroy()
S'il vous plaît noter que ce code ne soit pas encore terminée, par exemple, il n'a pas encore gérer correctement l'utilisateur ne pas sélectionner un fichier et l'annulation de l'opération.
EDIT: Lors d'une étude plus approfondie, il semble y avoir un problème de threading avec PyGTK. Le problème se produit dans la boucle while True
. J'ai remplacé ce code par un time.sleep(15)
, et de même, la boîte de dialogue de sélection de fichier mettra en pause. C'est un comportement assez étrange, et tout devrait fonctionner à l'intérieur d'un thread différent. Je suppose que la question est maintenant de savoir comment placer la boîte de dialogue de sélection de fichier dans son propre thread.
Je vais essayer dès que j'en aurai l'occasion. – Phanto
J'utilise un mélange de la méthode 'gobject.timeout_add()', et de ce que ptomato a suggéré de supprimer le thread. Cela fait apparaître le popup. Cependant, lorsque j'utilise un simple rappel, comment savoir quand la méthode 'doFileStuff()' est terminée? La méthode 'gobject.timeout_add()' renvoie un ID entier de la source de l'événement. Est-ce que la méthode 'gobject.signal_query()' le ferait? – Phanto
Je pense: http://pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--signal-query2 dit que le tuple contiendra 'le GType du retour de la fonction de rappel de signal'. Je suppose qu'il retournera None (ou équivalent de GType) si le callback n'est pas fini. –