在PyGObject内省中,线程在GTK w / Python中有变化吗? [英] Has threading in GTK w/ Python changed in PyGObject introspection?
问题描述
我第一次正在将一个程序从PyGTK转换为PyGObject内省,并且我已经通过线程攻击了一个障碍。我有一个需要一些时间才能完成的过程,所以我弹出一个对话框,其上有一个进度条,我使用一个线程来完成该过程并更新进度条。这在PyGTK中运行良好,但在转换为PyGObject之后,我得到了所有不正常的线程怪异:程序挂起,但它似乎挂在进程的不同部分等等。所以我得到的印象是某些东西已经改变,但我可以不知道是什么。
以下是这个简单的PyGTK进度条示例: http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html
如该页面所示,代码有效。我已经将它转换为PyGObject introspection,并且遇到了与我的程序中相同的问题:它挂起,没有正确更新进度条等。
导入线程
导入随机,时间
from gi.repository import Gtk,Gdk
#初始化gtk的线程引擎
Gdk.threads_init()
class FractionSetter(threading.Thread):
这个类设置进度条的小数部分
#Thread事件,停止该线程是否已设置。
stopthread = threading.Event()
def run(self):
运行方法,这是运行线程时运行的代码。
#从全局范围导入进度条小部件
全局进度条
#当stopthread事件未设置时,线程继续执行
not self.stopthread.isSet():
#获取gtk全局互斥量
Gdk.threads_enter()
#为分数
设置一个随机值progressbar.set_fraction(random。随机())
#释放gtk全局互斥
Gdk.threads_leave()
#延迟100ms直到下一次迭代
time.sleep(0.1)
def stop(self):
停止方法,设置事件以终止线程的主循环
self.stopthread.set()
def main_quit(obj):
main_quit函数, t停止线程和gtk的主循环
#从全局范围导入fs对象
全局fs
#停止线程和gtk的主循环
fs。 stop()
Gtk.main_quit()
#Gui bootstrap:窗口和进度条
window = Gtk.Window()
progressbar = Gtk.ProgressBar()
window.add(progressbar)
window.show_all()
#将'destroy'事件连接到main_quit函数
window.connect('destroy',main_quit)
#创建和启动线程
fs = FractionSetter()
fs.start()
Gtk.main()
$ c在gdk线程功能的文档中,它强调你首先必须在运行gdk_threads_init()之前运行g_thread_init(NULL)。但要运行它,你需要链接一些额外的库。如果我尝试通过自省来导入GLib,然后尝试运行GLib.thread_init(),则会出现以下错误:
>>> from gi.repository import GLib
>>> GLib.thread_init(无)
Traceback(最近一次调用的最后一个):
在< module>中,第1行的文件< stdin>
文件/usr/lib/python2.7/site-packages/gi/types.py,第44行,函数
返回info.invoke(* args)
glib.GError :找不到g_thread_init:`g_thread_init':/usr/lib/libglib-2.0.so.0:undefined symbol:g_thread_init
我认为这是因为额外的线程库没有链接。如果这是我的线程问题的原因,那我该如何使用GLib,就好像这些库已经链接了一样?
通过用Python编写的一些Gnome程序(Gnome Sudoku,在这种情况下,实际上帮了我几次时间)设法回答我自己的问题。 技巧是你必须在你的代码开头调用 GObject.threads_init()
,而不是 GLib.thread_init()
正如C文档所暗示的那样。
I'm in the process of converting a program from PyGTK to PyGObject introspection for the first time and I've hit a roadblock with threading. I have a process that takes some time to complete, so I pop up a dialog with a progress bar on it and I use a thread to do the process and to update the progress bar. This worked fine with PyGTK but after converting to PyGObject, I get all the usual improper threading weirdness: the program hangs, but it seems to hang in different parts of the process, etc. So I get the impression that something has changed but I can't figure out what.
Here's this simple PyGTK progressbar example: http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html
As presented on that page, the code works. I've converted it to PyGObject introspection and I get the same problems as in my program: it hangs, it doesn't properly update the progress bar, etc.
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()
In the documentation for Gdk's threading capabilities, it stresses that you first must run g_thread_init(NULL) before running gdk_threads_init(). But to run that, you need to link in some extra libraries. If I try to import GLib through introspection and then I try to run GLib.thread_init(), I get the following error:
>>> 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
I assume this is because the extra threading libraries weren't linked. If this is the cause of my threading problems, how can I work with GLib as if those libraries have been linked?
解决方案 I managed to answer my own question by poking through some Gnome programs written in Python (Gnome Sudoku, in this case, which actually has helped me a couple of times).
The trick is that you have to call GObject.threads_init()
at the beginning of your code, not GLib.thread_init()
as the C documentation implies.
这篇关于在PyGObject内省中,线程在GTK w / Python中有变化吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!