2014-09-01 29 views
0

我有问题:我打电话给thread.join(),我敢肯定线程正常工作的标准输出记录,但它无法更新GUIThread.join()不允许线程本身更新GUI

的例子是非常简单的:线程应该更新进度5倍:进度条开始全面清空,在时间0,并成为完全充满,在时间5 每次更新时每秒,所以它总共需要5秒钟。

thread.join()后会显示另一个窗口

但问题是,在thread.join()我可以看到只是标准输出记录,但进度条没有更新。我必须等5秒钟,然后我可以看到一个完全填满的进度条,最后显示另一个窗口。

,所以我不能看到任何更新我的GUI,我的进度,这些5秒

这期间是代码:

def Interrupt_Button_clicked(widget, args=()): 

    t = threading.Thread(target=pulsing2, args=()) 
    t.setDaemon(True) 
    t.start() 
    t.join() 
    builder.get_object('Azioni_Window').show() 


def pulsing2(): 

    progressbar.set_inverted(True) 
    fraction = 0.0 
    while True: 
     fraction += 0.2 
     progressbar.set_fraction(fraction) 
     print fraction # THIS WORKS CORRECTLY EVERY TIME, 5 TIMES IN TOTAL (1/0.2) 
     time.sleep(1) 
     if fraction == 1: 
      break 

progressbar = builder.get_object('Progressbar1') 
builder.get_object('Ferma_trovarete_Button').connect('clicked', Interrompi_Button_clicked) 
builder.get_object('Trovarete_Window').show() 
Gtk.main() 
+1

你不应该添加0.2五倍期望它等于1.0,因为0.2不能完全用二进制表示。如果它在这里工作,这是巧合。 – kindall 2014-09-01 01:06:44

+0

**打印分数**在时间5打印1.0,** Gtk.Progressbar.get_fraction()**返回我1.0 – FrancescoN 2014-09-01 01:18:25

+0

正如我所说,*如果它在这里工作,这是巧合。*因此,它的工作原理。这是巧合。 – kindall 2014-09-01 01:25:39

回答

1

您要更新的GUI来自GTK不支持的后台线程。如果您需要从后台线程更新GUI,请使用gobject.idle_add安排在主线程中更新小部件。

def pulsing2(callback=None): 

    progressbar.set_inverted(True) 
    fraction = 0.0 
    while True: 
     fraction += 0.2 
     gobject.idle_add(progressbar.set_fraction, fraction) 
     print fraction # THIS WORKS CORRECTLY EVERY TIME, 5 TIMES IN TOTAL (1/0.2) 
     time.sleep(1) 
     if fraction == 1: 
      break 
    gobject.idle_add(builder.get_object('Azioni_Window').show) 

您还需要从Interrupt_Button_clicked删除调用t.join(),因为它会阻止函数调用,这意味着GTK事件循环将无法运行的内部主线程和实际更新GUI小部件。

这么说,我觉得你可以重构这完全不使用线程,而是使用gobject.timeout_add安排您的更新代码运行每秒:

def Interrupt_Button_clicked(widget, args=()): 
    def cb(): 
     builder.get_object('Azioni_Window').show() 
     print ("pulsing2 is done") 

    pulsing2(callback=cb) 

def pulsing2(fraction=0.0, callback=None): 
    progressbar.set_inverted(True) 
    fraction += 0.2 
    progressbar.set_fraction(fraction) 
    print fraction # THIS WORKS CORRECTLY EVERY TIME, 5 TIMES IN TOTAL (1/0.2) 
    if fraction != 1: 
     gobject.add_timeout(1, pulsing2, fraction, callback) 
    else: 
     if callback: 
      gobject.idle_add(callback) 
+0

我想你有误解我的问题:主线程在子线程函数期间什么也不做。子线程工作,因为它每秒打印正确的部分,但我看不到任何更新到我的进度条。 – FrancescoN 2014-09-01 01:11:40

+0

@ Jimmy5nomana啊,我想我知道问题是什么。我会编辑我的答案。 – dano 2014-09-01 01:12:53

+0

我也试过gobject.idle_add,也许你的更好。让我们阅读代码 – FrancescoN 2014-09-01 01:19:52