我有问题:我调用thread.join(),我确定该线程正在通过stdout日志记录正确工作,但它无法更新GUI 即可。
示例非常简单:线程应该更新进度条5次:进度条在时间0开始完全清空,并在时间5完全填满。每次更新都会发生每秒,所以总共需要5秒钟。
在thread.join()之后会显示另一个窗口。
但问题是,在thread.join()的那一刻,我只能看到stdout日志记录,但进度条没有被更新。我必须等待5秒,然后我才能看到一个完全填充的进度条,最后显示另一个窗口。
所以我无法在5秒钟内看到我的GUI,我的进度条的任何更新
以下是代码:
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()
答案 0 :(得分: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)
您还需要从t.join()
中删除对Interrupt_Button_clicked
的调用,因为它会阻止函数调用中的主线程,这意味着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)