GTK+ interface graphique geler

cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008 - 9 févr. 2008 à 21:30
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008 - 13 févr. 2008 à 16:10
Bonjour à tous,
Voila j'ecris un programme en c (debutant) avec la bibliothèque GTK+ pour creer une interface graphique.
Je voudrais changer en temps reel le texte d'un label seulement mon interface graphique reste geler et ce jusqu'a la fin du traitement. D'après mes recherche c'est normal mais je ne ccomprend pas comment  remedier...

merci de me repondre

19 réponses

gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
10 févr. 2008 à 00:27
simple utilise un thread
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
10 févr. 2008 à 16:32
Yes, merci t'avais raison avec un thread ca fonctionne. Seulement il ya juste un petit soucis, le label s'affiche que si je bouge la souris (si je ne touche pas la souris le label ne s'affiche pas). Je trouve ca bizzar... Si t'as une idée de ce sui peut ce passer fait le moi savoir parce que moi je nage un peu...(je débute en prog).
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
10 févr. 2008 à 17:45
Tu utilises bien un système d'évément pour mettre a jour le label ? Tu modifies pas le label depuis ton thread quand meme ?
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
10 févr. 2008 à 17:49
... ...ben...en fait...si...
Un systeme d'evenement?
Je ne vois pas très bien...
Pourrais tu m'expliquer? dsl mais je débute et j'essaye d'apprendre petit à petit
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
10 févr. 2008 à 19:29
Aucune librairie de GUI n'est thread safe, c'est à dire que des que tu créés un thread, il est ABSOLUMENT interdit pour lui d'appeler des fonctions de la gui. En fait, gtk dispose de fonctions pour permettre ce genre de chose, mais c'est très délicat à utiliser (gtk_thread_enter/gtk_thread_leave (de mémoire)).

En règle général, des que tu veux modifier la gui, il faut stocker dans une variable protégée (cad protégé par un mutex dans ton cas pour éviter à un thread de lire la variable pdt alors qu'elle est en cours de modification par un autre thread). Ensuite, la gui vient périodiquement (avec un timer) lire le contenu de la variable pour se mettre à jour si nécessaire. Donc ca, c'est la méthode artisanale qui fonctionne à coup sur.

Normalement, le librairie te fournit des systèmes d'événements asynchrones. Dans ton thread tu envois un événement (avec une méthode push_event, je connais pas la fonction sous gtk, mais il doit y avoir l'équivalent) contenant les données pour mettre à jour ton label. L'intéret c'est que la GUI sait que cet événement provient d'un thread. Donc elle le stocke et le traite dès que possible dans le thread principal.

Mais j'ai jeté un rapide coup d'oeil sur la doc de gtk, c'est un peu le bordel (il semblerait) donc la méthode artisanale me semble la plus pratique pour toi. Il faudrait passer du temps sur la doc de gtk, mais si tu débutes, tu seras plus perdu qu'autre chose.
Donc tu créés une chaine de caractère et un mutex (http://library.gnome.org/devel/glib/stable/glib-Threads.html). Si tu sais pas ce que c'est => google.

Mais attention, tu te lances dans des trucs un peu technique. La pente risque d'etre un peu raide au début mais après t'arrives sur la plaine.

La doc intégrale de gtk/glib... à mettre en FAVORIS:
http://library.gnome.org/devel/references
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
10 févr. 2008 à 22:01
Et ben...Je viens de passer une heure et demi a chercher sur le net des explication sur tout ca mais ca reste toujours aussi obscure...pourquoi être obliger de proteger une variable si tu ne fais que la lire (par le thread gerant la gui)? et...................bref je pipe rien...

En tout cas petite explication du programme: il s'agit d'un chronometre. Deux voiture miniature envoie une trame chacun sur le port RS232, le programme doit reconnaitre ces trames et lancer un chrono dès la reception... En console pas trop de soucis mais pour l'interface graphique c'est une autre paire de manche...Mon soucis étant l'affichage des temps a chaque tour de voiture en temps reel. donc en ce moment j'en suis là : je lance le thread avec le label passer en parametre.

Une fois la trame recu modification de la chaine que le label contient puis mis a jour du label par un
gtk_label_set_text(GTK_LABEL(pTempLabel), tps_res);

Voila si quelqu'un peux m'éclairer, ce serait sympas...pour le mutex etc... je regarderais demain parce que là ca commence a me fatigué (moi qui penser etre arriver au bout du prog...)

En tout cas merci bcp luhtor de m'avoir accorder un peu de ton tps
0
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
10 févr. 2008 à 22:11
je comprend ton probleme mais bon defois soit le faire en mfc ou en api est plus simple surtout quand on est debutant

en api simple tu créer reelement un thread qui va verifier ta donnée pas besoin de passer par un mutex juste faire des validations

surtout plus faicile si tu ne fais qu'affiché des infos
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
10 févr. 2008 à 22:39
"pourquoi être obliger de proteger une variable si tu ne fais que la lire (par le thread gerant la gui)"
=> Car la prog multithreadé, c'est délicat. Si tu comprends pas pourquoi, admets le :) Mais c'est facile de trouver un exemple:

Imagines une chaine de caractère avec un 0 terminal, le thread écrivain efface momentanément ce 0 pour par exemple, rallonger la chaine. Mais Windows l'interrompt avant qu'il est totalement fini. Bref, la chaine ne possède plus de 0 terminal or le thread de lecture passe par la et souhaite lire le contenu, et la, tu imagines la suite. Il va lire la chaine, plus plein de merde jusqu'à trouver un 0 en mémoire. Windows interrompt ce thread puis rend la mains au thread écrivain qui finit son boulot. Conclusion de l'histoire, ton thread lecteur a lu n'importe quoi.

Lecon => empecher le thread de lecture d'accéder a la variable tant que le thread écrivain a pas terminé => créer un mutex.
0
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
10 févr. 2008 à 23:24
pas necessairement on peux empecher le thread de lecture et vice-versa de fonctionner si lautre est activé en utilisant les fonctions prevu a cette effet.

je comprend tres bien les programme multithreader mais j'utilise pas necessairement de mutex pour le faire j'utilise juste d'autre moyen
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
10 févr. 2008 à 23:36
Oui mais dans son cas, le thread de lecture c'est la GUI donc la bloquer n'est pas une solution.... Par ailleurs, "bloquer un thread pendant que l'autre tourne", alors dans ce cas, autant pas faire de thread.

"les fonctions prevu a cette effet"
Ah, de quelles fonctions parles tu ? A part un sémaphore, je vois pas.

"j'utilise juste d'autre moyen"
Il n'y pas vraiment d'autres moyens totalement surs. C'est sémaphore ou la catastrophe (sauf cas d'école).

Mais dans le cas d'une simple lecture de chaine, on peut tolérer le fait que l'espace d'un rafraichissement la chaine affichée soit incorrecte en faisant abstraction de sémaphores. Mais dans tous les cas, il faudra un timer pour mettre a jour le label depuis le thread principal.
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
11 févr. 2008 à 00:12
Un timer genre toutes les secondes, aller voir l'état de la chaine et mis a jour du label ? Ca risque pas de geler la gui (prb initial ?)
0
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
11 févr. 2008 à 00:31
a oui c'est cela cest les semaphore j'avais oublié le nom mais bon j'ai verifié sur internet et les deux moyens sont possible ..
je créais toujours des semaphore j'avais pas vraiment fais de mutex car j'utilse souvent le partage des données qui on déjà une protection .

attention empecher l'execution d'un thread surtout s'il ne fais que lire une variable ne le bloque pas il ne l'execute juste pas mais bon pour faire cela il faut joué avec les priorité des threads.

bon alors raf15 les choix sont soit mutex ou semaphore  . je te conseil de rechercher sur le sujet. tu peux chercher sur le multithreading il a de bon exemple sur le web . pas besoin de timer fais juste protégé l'acces des données sur ton thread il donnais l'exemple si on utilisait pas de protection .

bon salut sans rancune.
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
11 févr. 2008 à 13:09
S'il n'utilise pas de timer, il lui faudra alors un événement pour savoir quand le thread principal doit lire la chaine.

"Un timer genre toutes les secondes, aller voir l'état de la chaine et
mis a jour du label ? Ca risque pas de geler la gui (prb initial ?)"
=> bas non pas du tout. Pourquoi veux tu que ca la bloque ?

"bon alors raf15 les choix sont soit mutex ou semaphore"
=> perso, je considère un mutex comme faisant partie de l'ensemble des sémaphores. Bref des objets contre les accès multiples.
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
11 févr. 2008 à 13:51
Ok merci bien luhtor je vais essyer avec un timer voir ce que ca donne ce soir.

Par contre juste une derniere petite question : la chaine de caractère contenant les infos a afficher en temps réel je dois la déclarer en tant que variable global ou juste dans le thread d'ecriture (étant donné que la memoire est partagé) ?
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
11 févr. 2008 à 13:56
Il faut la déclarer là où tes deux threads peuvent y accéder.
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
11 févr. 2008 à 21:28
Je viens d'essayer avec un timer sur le thread de lecture et la gui est geler :

    //timer=0;
    //while(timer<100000)
    while(1)
    {
         gtk_label_set_text(GTK_LABEL(pLabelTest), tps_res);
         gtk_widget_show_all(pWindow);
         //gtk_widget_show(pLabelTest);
         //timer++;
         //sleep(1);
    }

J'ai aussi essyer avec ce qu'il y a en commentaire mais idem ou alors le label ne se met pas a jour...Une idée ?
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
11 févr. 2008 à 23:23
Oualala, c'est pas un timer que tu utilises la... Comment  veux tu que la gui continue de tourner si tu la bloques...

Il faut utiliser la fonction:
http://library.gnome.org/devel/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
13 févr. 2008 à 15:55
Yes, je te rermercie tuhtor pour ta patience et de m'avoir accorder de ton temps. Ca fonctionne avec la fonction g_timeout_add(), il ya juste un petit soucis : la fenetre se ferme aptès le traitement mais ca ne doit pas être dur a résoudre... En tout cas encore merci
0
cs_Raf15 Messages postés 15 Date d'inscription vendredi 7 décembre 2007 Statut Membre Dernière intervention 13 février 2008
13 févr. 2008 à 16:10
Ok, problème résolu... Voilà il ne reste plus qu'a faire la une fenetre un peu plus sympas et c'est finis. Donc merci à tous  (particulièrement luhtor)

chao...
0
Rejoignez-nous