2 votes

Le thread ne fonctionne que sur les événements de l'interface utilisateur - pygtk

Je suis en train de développer une application multithread en pygtk en utilisant rapidement les threads. Je suis donc en train d'expérimenter diverses possibilités et j'ai découvert que mon thread ne fonctionne que lorsque je fais quelque chose dans le gui Voici mon code

t = threading.Thread(target=self.calc,args=(treeiter))
t.daemon = True
t.start()

    def calc(self,treeiter):
        store=self.builder.get_object('liststore1')
        per=0
        while 1:
            print "Calcing and changing percent,per="+str(per)
            tore.set_value(treeiter,4,str(int(per))+"%")
            per+=1
            time.sleep(1)

J'essaie de mettre à jour la valeur d'un liststore par thread mais il n'est mis à jour que lorsque je clique sur un bouton ou sur d'autres événements de l'interface utilisateur, pourquoi en est-il ainsi ? pourquoi le thread ne tourne-t-il pas en arrière-plan ?

4voto

vbroto Points 723

Threads et GTK ne font pas toujours bon ménage. Il y a quelques astuces qui aident, mais ne soyez pas surpris d'avoir des bugs bizarres. J'ai récemment supprimé tous les threads d'une application et cela fonctionne beaucoup mieux.

La première chose à laquelle vous devez penser est donc de savoir si vous pouvez réécrire votre application pour tirer parti des méthodes asynchrones de GLib.

Si vous tenez à avoir des fils, gardez ces deux règles à l'esprit :

  1. Appeler GLib.treads_init() le plus tôt possible dans votre code
  2. Lorsque vous appelez les événements de l'interface graphique dans un thread, intégrez-les dans une fonction GLib.idle_add()

Il s'agit de règles et non de lignes directrices. Vous devez siempre le faire lorsque l'on travaille avec des fils.

3voto

Thomas15v Points 1533

L'utilisation de time.sleep() n'est pas une bonne idée lorsque vous utilisez gtk. Vous pouvez essayer d'utiliser un événement de type timer. (Je n'utilise plus rapidement mais cela devrait fonctionner je pense).

from gi.repository import GLib

class Just_for_correct_coding():
    self.per = int()

    def start(self):
        GLib.timeout_add_seconds(1, self.calc)

    def calc(self,treeiter):
        store=self.builder.get_object('liststore1')
        print "Calcing and changing percent,per="+str(self.per)
        tore.set_value(treeiter,4,str(int(self.per))+"%")
        self.per+=1
        return True #important if you want to keep the timer running

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X