How refresh a DrawingArea in PyGTK?
I have an interface created with Glade. It contains a DrawingArea and buttons.
I tried to create a Thread to refresh every X time my Canva. After a few seconds, I get error messages like:
"X Window Server 0.0", "Fatal Error IO 11"
Here is my code :
import pygtk
pygtk.require("2.0")
import gtk
import Canvas
import threading as T
import time
import Map
gtk.gdk.threads_init()
class Interface(object):
class ThreadCanvas(T.Thread):
"""Thread to display the map"""
def __init__(self, interface):
T.Thread.__init__(self)
self.interface = interface
self.started = True
self.start()
def run(self):
while self.started:
time.sleep(2)
self.interface.on_canvas_expose_event()
def stop(self):
self.started = False
def __init__(self):
self.interface = gtk.Builder()
self.interface.add_from_file("interface.glade")
#Map
self.map = Map.Map(2,2)
#Canva
self.canvas = Canvas.MyCanvas(self.interface.get_object("canvas"),self.game)
self.interface.connect_signals(self)
#Thread Canvas
self.render = self.ThreadCanvas(self)
def on_btnChange_clicked(self, widget):
#Change map
self.map.change()
def on_interface_destroy(self, widget):
self.render.stop()
self.render.join()
self.render._Thread__stop()
gtk.main_quit()
def on_canvas_expose_event开发者_如何学Go(self):
st = time.time()
self.canvas.update(self.map)
et = time.time()
print "Canvas refresh in : %f times" %(et-st)
def main(self):
gtk.main()
How can i fix these errors ?
To use Python threads in PyGTK, you need to surround any access to shared GTK objects with gtk.gdk.threads_enter() and gtk.gdk.threads_leave(). See also the threads_enter() method.
You might even be better off using GTKs functions for periodic function calls, such as timeout_add(...) and timeout_add_seconds(...) (note that recently these functions moved around a bit, and in your installation they might be in GObject and not GLib).
Some other notes:
- Subclassing Thread objects is the Java way of doing things, not the Python way. The Python way is to define a function or callable object that what you need and pass it to a Thread constructor.
- You should not be using
_Thread__stop()
. It is name mangled for a reason, which is that it forms part of the internal mechanism of the Thread object and is not for normal public use. Instead, you should use one of the thread-safe objects (eg. a Condition object) and check it from the function you passed to your Thread object in step one. Alternatively, set your Thread as a daemon, so it will automatically die when the program exits. - The usual extension for GTKBuilder files is ".ui", not ".glade" (even though Glade itself appends ".glade" as the default extension.)
I hope this helps.
精彩评论