Exécuter du code au démarrage de gtk.main()
Bonjour,
Je souhaite, dans une application GTK, exécuter du code au lancement.
Je veux que pendant l'exécution de ce code (qui peut prendre un peu de temps), un popup (MessageDialog) soit affiché pour dire de patienter.
Le problème, c'est que ce message ne sera visible que quand gtk.main() sera appelé. Or je ne peux plus rien faire après gtk.main().
La première idée que j'ai eue, c'est de lancer ce code dans un thread. Ça a l'air de poser pas mal de problèmes... J'ai bien protégé le code du thread par gtk.gdk.threads_enter() et gtk.gdk.threads_leave(), mais malgré tout j'ai des erreurs (accès concurrent à des widgets à priori, car dans le code du thread, à la fin, je dois mettre à jour l'affichage de l'application).
J'aurais donc tendance à penser que ce n'est pas la bonne solution.
Est-ce qu'il n'existerait pas, plus simplement, un event sur lequel je pourrais m'enregistrer, qui serait appelé quand l'affichage de l'application est terminé, soit juste après l'appel à gtk.main().
Ça me permettrait d'appeler mon code dans le contexte de la "main loop" GTK et ne poserait plus aucun problème.
Merci.
Exemple pour reproduire le problème
Bonjour,
J'ai finalement réussi à écrire un petit programme de test qui illustre mon problème.
Je pense que ce sera plus simple pour comprendre ce que je veux dire :)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
#!/usr/bin/env python
import gobject
import gtk
from threading import Thread
import time
def _destroy(widget, data=None):
gtk.main_quit()
def _thread():
gobject.idle_add(_thread_actions)
def _thread_actions():
message_dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
message_dialog.set_markup('Patientez...')
message_dialog.show_all()
gtk.gdk.threads_enter()
message_dialog.set_markup('Etape 1')
#gtk.main_iteration()
gtk.gdk.threads_leave()
time.sleep(1)
gtk.gdk.threads_enter()
message_dialog.set_markup('Etape 2')
#gtk.main_iteration()
gtk.gdk.threads_leave()
time.sleep(1)
message_dialog.destroy()
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect('destroy', _destroy)
vbox = gtk.VBox(False)
label = gtk.Label()
label.set_text('Mon application')
vbox.pack_start(label, False)
window.add(vbox)
window.maximize()
window.set_title('test')
window.show_all()
gtk.gdk.threads_init()
thread = Thread(None, _thread, 'mon thread')
thread.start()
gtk.main() |
On constate déjà que la window principale n'affiche son contenu ("Mon application") que quand le thread est fini.
Mais surtout, le contenu de mon popup ne s'affiche jamais. Les appels à gtk.main_iteration() (si je les décommente) ne changent rien.
Pourtant, si je supprime l'appel à message_dialog.destroy(), je constate que le contenu s'affiche à la fin du thread.
J'espère que c'est plus clair avec cet exemple.
Merci d'avance pour votre aide...