【问题标题】:GObject.idle_add(func), my program hangsGObject.idle_add(func),我的程序挂起
【发布时间】:2014-11-17 00:56:57
【问题描述】:

我不知道为什么我的程序会挂起,我已经阅读了几个关于此的主题。

结果是当我点击Config_Window_Button1时,我的Config_Window会冻结一会儿,time.sleep()要求的时间

然后出现 Network_Window 但 GObject.idle_add() 似乎只运行了一次(分数调整为 0.25);我在该进度条中看不到任何动作,而有趣的是print("def pulse running") 定期运行

所以:

1) 为什么 Config_Window 会冻结 S 秒,而 time.sleep(S) 是在 GObject.idle_add() 之后?

2) 为什么我的 GUI 没有更新?

GObject.threads_init()
builder = Gtk.Builder()
builder.add_from_file('UI2.glade')
builder.get_object('Config_Window').show()

progressbar = builder.get_object('Progressbar1')
progressbar.set_inverted(True)
fraction = 0.0
builder.get_object('Config_Window_Button1').connect('clicked', collega_GUI) 


def collega_GUI(widget, args=()):

    builder.get_object('boxNetwork').show_all()
    builder.get_object('Network_Window').show()
    progressbar.set_pulse_step(0.25)

    pulse()
    print 'collega_GUI has ended'


def pulse():

    while True:
        GObject.idle_add(progressbar.pulse)
        time.sleep(1)
        print 'def pulse running'

【问题讨论】:

    标签: python multithreading pygtk gobject


    【解决方案1】:

    问题是你在pulse 函数中有一个while True 循环。这意味着控制永远不会离开pulse 并返回到您的事件循环,这意味着 GTK 永远不会真正更新 UI。您可以通过重复调度 pulse 以使用 timeout_add 运行而不是使用无限循环来解决此问题。

    def pulse():
        progress_bar.pulse()
        GObject.timeout_add(1000, pulse) # pulse it again in 1 second.
        print 'def pulse running'
    

    编辑:

    看起来您实际上是在尝试在这里使用多个线程,在这种情况下,您可以保持 pulse 原样,只要您实际在后台线程中启动它:

    def collega_GUI(widget, args=()):
    
        builder.get_object('boxNetwork').show_all()
        builder.get_object('Network_Window').show()
        progressbar.set_pulse_step(0.25)
    
        self.pulse_thread = threading.Thread(target=pulse)
        self.pulse_thread.start()
        print 'collega_GUI has ended'
    
    
    def pulse():
        while True:
            GObject.idle_add(progressbar.pulse)
            time.sleep(1)
            print 'def pulse running'
    

    【讨论】:

    • 您好,感谢您的回复。你已经回答了我一个非常相似的问题,这次我打算试试这个:manojbits.wordpress.com/2012/08/11/multithreading-in-pygtk
    • 我还注意到 time.sleep() 和 GObject.idle_add() 不能按预期一起工作(即使没有 while 循环),因为 GUI 冻结了。你知道更多吗?
    • @Jimmy5nomama 你在这里只使用一个线程,所以无论何时你使用time.sleep,无论你睡多久,你都会阻塞事件循环。这就是您的代码和您链接到的示例之间的区别;该示例使用后台线程运行无限循环,因此 GUI 永远不会被阻塞。如果您要在后台线程中运行 pulse,您的示例就可以正常工作。
    • 除了你必须 使用来自不同线程的GTK+ API:只有一个线程可以修改GUI,并且是调用Gtk的线程。主要()。
    • @ebassi 只要您只通过Gobject.idle_add 访问小部件,您就可以从另一个线程使用 GTK 的 API。或者也许这就是你想说的 - 不要直接使用 GTK+,只使用 gobject.idle_add/object.timeout_add?
    猜你喜欢
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2013-01-16
    • 2015-05-18
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    相关资源
    最近更新 更多