Ich entwickle eine Multithread-Anwendung in pygtk mit fast und stecke mit Threads fest. Ich experimentiere also mit verschiedenen Möglichkeiten und habe festgestellt, dass mein Thread nur funktioniert, wenn ich etwas in der GUI mache. Hier ist mein 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)
Ich versuche, den Wert in einem liststore
Thread zu aktualisieren, aber er wird nur aktualisiert, wenn ich auf eine Schaltfläche klicke oder ein anderes GUI-Ereignis auftritt. Warum ist das so? Warum läuft der Thread nicht im Hintergrund?
Antwort1
Threads und GTK funktionieren nicht immer reibungslos miteinander. Es gibt ein paar Tricks, die helfen, aber wundern Sie sich nicht über seltsame Fehler. Ich habe kürzlich alle Threads aus einer Anwendung entfernt und es fühlt sich viel besser an.
Sie sollten also zunächst darüber nachdenken, ob Sie Ihre Anwendung umschreiben können, um die asynchronen Methoden von GLib zu nutzen.
Wenn Sie auf Threads bestehen, beachten Sie diese beiden Regeln:
- Rufen Sie GLib.treads_init() so früh wie möglich in Ihrem Code auf
- Wenn Sie GUI-Ereignisse in einem Thread aufrufen, schließen Sie sie in ein GLib.idle_add() ein
Dies sind Regeln, keine Richtlinien. Sie müssenstetsTun Sie dies, wenn Sie mit Threads arbeiten.
Antwort2
Die Verwendung von time.sleep() ist keine gute Idee, wenn Sie GTK verwenden. Sie könnten versuchen, ein Timer-Ereignis zu verwenden. (Ich verwende Quickly nicht mehr, aber ich denke, das sollte funktionieren.)
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