我有一个使用 Glade 创建的界面。它包含一个 DrawingArea 和按钮。
我尝试创建一个线程,每隔 X 次刷新我的 Canva。几秒钟后,我收到如下错误消息:
“X 窗口服务器 0.0”、“ fatal error IO 11”
这是我的代码:
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(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()
如何修复这些错误?
请您参考如下方法:
要在 PyGTK 中使用 Python 线程,您需要用 gtk.gdk.threads_enter() 包围对共享 GTK 对象的任何访问。和 gtk.gdk.threads_leave() .另见 threads_enter()方法。
您甚至可能更好地使用 GTK 函数进行周期性函数调用,例如 timeout_add(...)和 timeout_add_seconds(...) (请注意,最近这些函数移动了一点,在您的安装中它们可能位于 GObject 而不是 GLib 中)。
一些其他注意事项:
- 子类化 Thread 对象是 Java 的做事方式,而不是 Python 的方式。 Python 方法是定义一个您需要的函数或可调用对象,并将其传递给 Thread 构造函数。
- 您不应该使用
_Thread__stop()。它的名称被破坏是有原因的,这是因为它构成了 Thread 对象的内部机制的一部分,并且不供正常的公共(public)使用。相反,您应该使用一个线程安全对象(例如 Condition 对象)并从您在第一步中传递给 Thread 对象的函数中检查它。或者,将您的 Thread 设置为守护进程,这样当程序退出时它会自动死掉。 - GTKBuilder 文件的通常扩展名是“.ui”,而不是“.glade”(尽管 Glade 本身附加了“.glade”作为默认扩展名。)
希望对您有所帮助。
