You are not logged in.
Pages: 1
Hi everyone,
I'm working on a project for a museum, as a volunteer. I'm writing a piece of software that interacts with an Arduino, and then displays data to a computer screen (an old iBook G4 running Debian). I'm having some trouble with my code, so I broke it down and am now trying to figure out how to change the contents of a label in pygtk. Here's my code:
import pygtk
import gtk
import serial
import threading
pygtk.require('2.0')
class doThread(threading.Thread):
def run(self):
global label
label.set_markup("<span font='Comic Sans 200'>hello</span>")
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_border_width(100)
window.set_title("program")
label = gtk.Label(" ")
frame = gtk.Frame(" ")
frame.add(label)
window.add(frame)
frame.show()
window.show_all()
label.set_markup("<span font='Comic Sans 200'>hi</span>")
print "HERE!"
test = False
dt = doThread(label)
dt.start()
gtk.main()
when I run it, I get this error:
File "gui.py", line 39, in <module>
dt = doThread(label)
File "/usr/lib/python2.7/threading.py", line 438, in __init__
assert group is None, "group argument must be None for now"
AssertionError: group argument must be None for now
What am I doing wrong? I've spent an hour trying to figure this out!
Thanks,
Jordan
Offline
Nevermind. I found some code online, and modified it. Here it is:
import threading
import random, time
import gtk
#Initializing the gtk's thread engine
gtk.threads_init()
global label1
class FractionSetter(threading.Thread):
"""This class sets the fraction of the progressbar"""
#Thread event, stops the thread if it is set.
stopthread = threading.Event()
def run(self):
"""Run method, this is the code that runs while thread is alive."""
#While the stopthread event isn't setted, the thread keeps going on
while not self.stopthread.isSet() :
# Acquiring the gtk global mutex
gtk.threads_enter()
#Setting a random value for the fraction
label.set_markup("<span font='Comic Sans 200'>hello</span>")
# Releasing the gtk global mutex
gtk.threads_leave()
#Delaying 100ms until the next iteration
time.sleep(0.1)
def stop(self):
"""Stop method, sets the event to terminate the thread's main loop"""
self.stopthread.set()
def main_quit(obj):
"""main_quit function, it stops the thread and the gtk's main loop"""
#Importing the fs object from the global scope
global fs
#Stopping the thread and the gtk's main loop
fs.stop()
gtk.main_quit()
#Gui bootstrap: window and progressbar
window = gtk.Window()
window.set_border_width(100)
label = gtk.Label()
window.add(label)
window.show_all()
#Connecting the 'destroy' event to the main_quit function
window.connect('destroy', main_quit)
#Creating and starting the thread
fs = FractionSetter()
fs.start()
gtk.main()
Offline
I do not mean any offense, but the reason for this exception is so obvious that you really are not ready to write GUI programs in Python, if you didn't figure the reason out within an hour.
In "doThread(label)" you pass "label" as first parameter to the "__init__()" method of "doThread", but you didn't define "doThread.__init__()" and hence the call delegates to the inherited "threading.Thread.__init__()". As you can see in the documentation of "threading.Thread.__init__()", this parameter must be "None" currently:
[…]group should be None; reserved for future extension when a ThreadGroup class is implemented.[…]
The exception is merely telling you that you've violated this requirement because "label" is obviously not "None". Since you didn't define "doThread.__init__()", I don't understand how you even got the idea of passing "label" as parameter here, especially since you're accessing "label" via "global" from "run()" anyway.
However, the whole idea of this code is broken. No GUI toolkit is thread-safe. GUI widgets must not directly be accessed from any other thread than the one the main loop ("gtk.main()" in this case) is started from, neither in Gtk nor in any other GUI toolkit around. This thread is normally called the “main thread”. I do not know Gtk well enough to tell you how Gtk handles inter-thread communication. Search for a tutorial on thread usage in Gtk.
By the way, this forum supports code formatting via the "code" tag.
Edit: Your second code snippet fixes the original error, but it still does not respect the thread safety requirements of GUI toolkits.
Last edited by lunar (2012-03-20 21:26:50)
Offline
I do not mean any offense, but the reason for this exception is so obvious that you really are not ready to write GUI programs in Python, if you didn't figure the reason out within an hour.
In "doThread(label)" you pass "label" as first parameter to the "__init__()" method of "doThread", but you didn't define "doThread.__init__()" and hence the call delegates to the inherited "threading.Thread.__init__()". As you can see in the documentation of "threading.Thread.__init__()", this parameter must be "None" currently:
[…]group should be None; reserved for future extension when a ThreadGroup class is implemented.[…]
The exception is merely telling you that you've violated this requirement because "label" is obviously not "None". Since you didn't define "doThread.__init__()", I don't understand how you even got the idea of passing "label" as parameter here, especially since you're accessing "label" via "global" from "run()" anyway.
However, the whole idea of this code is broken. No GUI toolkit is thread-safe. GUI widgets must not directly be accessed from any other thread than the one the main loop ("gtk.main()" in this case) is started from, neither in Gtk nor in any other GUI toolkit around. This thread is normally called the “main thread”. I do not know Gtk well enough to tell you how Gtk handles inter-thread communication. Search for a tutorial on thread usage in Gtk.
By the way, this forum supports code formatting via the "code" tag.
Edit: Your second code snippet fixes the original error, but it still does not respect the thread safety requirements of GUI toolkits.
No offense taken. Yeah, the second code I just posted keeps freezing... I'm going to try GTK thread thing.
Offline
Pages: 1