Als jemand, der neu in der GUI-Entwicklung in Python (mit pyGTK) ist, habe ich gerade angefangen, etwas über Threading zu lernen. Um meine Fähigkeiten zu testen, habe ich ein einfaches kleines GTK-Interface mit einem Start/Stop-Knopf geschrieben. Das Ziel ist, dass, wenn es angeklickt wird, ein Thread startet, der schnell eine Zahl im Textfeld erhöht, während die GUI reaktionsfähig bleibt.
Die grafische Benutzeroberfläche funktioniert einwandfrei, aber ich habe Probleme mit dem Threading. Wahrscheinlich ist es ein einfaches Problem, aber mein Verstand ist für den heutigen Tag ziemlich kaputt. Unten habe ich zuerst den Trackback des Python-Interpreters eingefügt, gefolgt von dem Code. Sie können gehen zu http://drop.io/pxgr5id um sie herunterzuladen. Ich verwende bzr für die Revisionskontrolle. Wenn Sie also eine Änderung vornehmen und sie wieder ablegen möchten, übertragen Sie die Änderungen bitte. Ich füge den Code auch unter http://dpaste.com/113388/ weil es Zeilennummern haben kann, und dieses Markdown-Zeug bereitet mir Kopfschmerzen.
Aktualisierung 27. Januar, 15:52 EST: Ein leicht aktualisierter Code kann hier gefunden werden: http://drop.io/threagui/asset/thread-gui-rev3-tar-gz
Rückverfolgung
crashsystems@crashsystems-laptop:~/Desktop/thread-gui$ python threadgui.pybtnStartStop clicked
Traceback (most recent call last):
File "threadgui.py", line 39, in on_btnStartStop_clicked
self.thread.stop()
File "threadgui.py", line 20, in stop
self.join()
File "/usr/lib/python2.5/threading.py", line 583, in join
raise RuntimeError("cannot join thread before it is started")
RuntimeError: cannot join thread before it is started
btnStartStop clicked
threadStop = 1
btnStartStop clicked
threadStop = 0
btnStartStop clicked
Traceback (most recent call last):
File "threadgui.py", line 36, in on_btnStartStop_clicked
self.thread.start()
File "/usr/lib/python2.5/threading.py", line 434, in start
raise RuntimeError("thread already started")
RuntimeError: thread already started
btnExit clicked
exit() called
Code
#!/usr/bin/bash
import gtk, threading
class ThreadLooper (threading.Thread):
def __init__ (self, sleep_interval, function, args=[], kwargs={}):
threading.Thread.__init__(self)
self.sleep_interval = sleep_interval
self.function = function
self.args = args
self.kwargs = kwargs
self.finished = threading.Event()
def stop (self):
self.finished.set()
self.join()
def run (self):
while not self.finished.isSet():
self.finished.wait(self.sleep_interval)
self.function(*self.args, **self.kwargs)
class ThreadGUI:
# Define signals
def on_btnStartStop_clicked(self, widget, data=None):
print "btnStartStop clicked"
if(self.threadStop == 0):
self.threadStop = 1
self.thread.start()
else:
self.threadStop = 0
self.thread.stop()
print "threadStop = " + str(self.threadStop)
def on_btnMessageBox_clicked(self, widget, data=None):
print "btnMessageBox clicked"
self.lblMessage.set_text("This is a message!")
self.msgBox.show()
def on_btnExit_clicked(self, widget, data=None):
print "btnExit clicked"
self.exit()
def on_btnOk_clicked(self, widget, data=None):
print "btnOk clicked"
self.msgBox.hide()
def on_mainWindow_destroy(self, widget, data=None):
print "mainWindow destroyed!"
self.exit()
def exit(self):
print "exit() called"
self.threadStop = 1
gtk.main_quit()
def threadLoop(self):
# This will run in a thread
self.txtThreadView.set_text(str(self.threadCount))
print "hello world"
self.threadCount += 1
def __init__(self):
# Connect to the xml GUI file
builder = gtk.Builder()
builder.add_from_file("threadgui.xml")
# Connect to GUI widgets
self.mainWindow = builder.get_object("mainWindow")
self.txtThreadView = builder.get_object("txtThreadView")
self.btnStartStop = builder.get_object("btnStartStop")
self.msgBox = builder.get_object("msgBox")
self.btnMessageBox = builder.get_object("btnMessageBox")
self.btnExit = builder.get_object("btnExit")
self.lblMessage = builder.get_object("lblMessage")
self.btnOk = builder.get_object("btnOk")
# Connect the signals
builder.connect_signals(self)
# This global will be used for signaling the thread to stop.
self.threadStop = 1
# The thread
self.thread = ThreadLooper(0.1, self.threadLoop, (1,0,-1))
self.threadCounter = 0
if __name__ == "__main__":
# Start GUI instance
GUI = ThreadGUI()
GUI.mainWindow.show()
gtk.main()