在PyGObject自省中,带有Python的GTK中的线程是否已更改?

发布于 2021-01-29 15:14:22

我正在第一次将程序从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()

在有关Gdk线程功能的文档中,它强调您必须先运行g_thread_init(NULL),然后再运行gdk_threads_init()。但是要运行它,您需要链接一些额外的库。如果我尝试通过自省导入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

我认为这是因为未链接额外的线程库。如果这是导致我的线程问题的原因,那么如何像那些库已链接一样使用GLib?

关注者
0
被浏览
43
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我设法通过用Python编写的一些Gnome程序(在本例中为Gnome Sudoku,实际上帮助了我两次)来回答自己的问题。

    诀窍在于您必须GObject.threads_init()在代码的开头调用,而不是GLib.thread_init()C文档所暗示的那样。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看