Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GTK w/Python中的线程在PyGObject内省中是否发生了变化?_Python_Multithreading_Gtk_Pygtk_Pygobject - Fatal编程技术网

GTK w/Python中的线程在PyGObject内省中是否发生了变化?

GTK w/Python中的线程在PyGObject内省中是否发生了变化?,python,multithreading,gtk,pygtk,pygobject,Python,Multithreading,Gtk,Pygtk,Pygobject,我正在第一次将一个程序从PyGTK转换为PyGObject内省的过程中,我遇到了线程方面的障碍。我有一个过程需要一些时间才能完成,所以我弹出一个对话框,上面有一个进度条,我使用一个线程来完成这个过程并更新进度条。这在PyGTK中运行得很好,但在转换到PyGObject之后,我遇到了所有常见的不正确的线程问题:程序挂起,但它似乎挂在进程的不同部分,等等。因此,我觉得有些东西已经改变了,但我不知道是什么 下面是一个简单的PyGTK progressbar示例: 正如该页所示,代码是有效的。我已经将它

我正在第一次将一个程序从PyGTK转换为PyGObject内省的过程中,我遇到了线程方面的障碍。我有一个过程需要一些时间才能完成,所以我弹出一个对话框,上面有一个进度条,我使用一个线程来完成这个过程并更新进度条。这在PyGTK中运行得很好,但在转换到PyGObject之后,我遇到了所有常见的不正确的线程问题:程序挂起,但它似乎挂在进程的不同部分,等等。因此,我觉得有些东西已经改变了,但我不知道是什么

下面是一个简单的PyGTK progressbar示例: 正如该页所示,代码是有效的。我已经将它转换为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线程功能的文档中,它强调在运行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
>>从gi.repository导入GLib
>>>GLib.thread_init(无)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python2.7/site packages/gi/types.py”,第44行,在函数中
返回信息。调用(*args)
glib.GError:找不到g_thread_init:'g_thread_init':/usr/lib/libglib-2.0。so.0:未定义的符号:g_thread_init

我想这是因为额外的线程库没有链接。如果这是我线程问题的原因,我如何才能像那些库已经被链接一样使用GLib呢?

我通过浏览一些用Python编写的Gnome程序(在本例中,Gnome数独实际上已经帮助了我好几次)来回答我自己的问题


诀窍在于,您必须在代码开始时调用
GObject.threads\u init()
,而不是像C文档所暗示的那样调用
GLib.thread\u init()

我只想说声谢谢。伙计,使用这些东西90%都是谷歌搜索。非常感谢!我遇到了这个问题,不知道哪里出了问题。我希望PyGObject有一些特定的文档,而不仅仅是“检查C文档”,这是对这个答案的现代更新:GObject.threads_init()和GLib.threads_init()是同义词,在PyGObject v3.10.2及更高版本中实际上两者都不需要。另请参见:@SimonFeltman同样,在现代GTK中,我们将放弃使用
Gdk.threads\u enter()
Gdk.threads\u leave()
,并使用诸如
idle\u add(lambda:progressbar.set\u france(random.random())
之类的调用来运行实际运行主循环的线程中的所有GUI代码。任何其他操作都会导致崩溃和头痛。您不应该使用
Gdk.threads\u enter()
Gdk.threads\u leave()来包装对
Gtk.main()
的调用吗?我看到的所有C代码示例都是这样做的。例如。: