27 python gtk multithreading pygtk pygobject
我正在第一次将程序从PyGTK转换为PyGObject内省,我遇到了一个带有线程的障碍.我有一个需要一些时间才能完成的过程,所以我弹出一个带有进度条的对话框,我使用一个线程来完成这个过程并更新进度条.这对PyGTK工作得很好,但在转换为PyGObject之后,我得到了所有常见的不正确的线程怪异:程序挂起,但它似乎挂在过程的不同部分,等等.所以我得到的印象是事情发生了变化,但我可以弄清楚是什么.
这是一个简单的PyGTK进度条示例:http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html 如该页面上所示,代码可以正常工作.我把它转换为PyGObject内省,我遇到了与我的程序相同的问题:它挂起,它没有正确更新进度条等.
import threading
import random, time
from gi.repository import Gtk, Gdk
#Initializing the gtk's thread engine
Gdk.threads_init()
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."""
#Importing the progressbar widget from the global scope
global progressbar
#While the stopthread event isn't setted, the thread keeps going on
while not self.stopthread.isSet() :
# Acquiring the gtk global mutex
Gdk.threads_enter()
#Setting a random value for the fraction
progressbar.set_fraction(random.random())
# Releasing the gtk global mutex
Gdk.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()
progressbar = Gtk.ProgressBar()
window.add(progressbar)
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()
Run Code Online (Sandbox Code Playgroud)
在Gdk的线程功能文档中,它强调在运行gdk_threads_init()之前首先必须运行g_thread_init(NULL).但要运行它,您需要链接一些额外的库.如果我尝试通过内省导入GLib然后我尝试运行GLib.thread_init(),我收到以下错误:
>>> from gi.repository import GLib
>>> GLib.thread_init(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
glib.GError: Could not locate g_thread_init: `g_thread_init': /usr/lib/libglib-2.0.so.0: undefined symbol: g_thread_init
Run Code Online (Sandbox Code Playgroud)
我认为这是因为没有链接额外的线程库.如果这是我的线程问题的原因,我如何使用GLib,就像这些库已被链接一样?
小智 27
我设法通过一些用Python编写的Gnome程序来回答我自己的问题(Gnome Sudoku,在这种情况下,它实际上帮助了我几次).
诀窍是你必须GObject.threads_init()在代码的开头调用,而不是GLib.thread_init()像C文档所暗示的那样.