我认为值得指出的是,这是一种@mhall建议的复杂方法。
本质上,您必须先运行此命令,然后再运行async_call函数。
如果您想了解它的工作原理,可以使用睡眠定时器并按住按钮。除了有示例代码外,它与@mhall的答案基本相同。
基于此,这不是我的工作。
import threading
import time
from gi.repository import Gtk, GObject
# calls f on another thread
def async_call(f, on_done):
if not on_done:
on_done = lambda r, e: None
def do_call():
result = None
error = None
try:
result = f()
except Exception, err:
error = err
GObject.idle_add(lambda: on_done(result, error))
thread = threading.Thread(target = do_call)
thread.start()
class SlowLoad(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Hello World")
GObject.threads_init()
self.connect("delete-event", Gtk.main_quit)
self.button = Gtk.Button(label="Click Here")
self.button.connect("clicked", self.on_button_clicked)
self.add(self.button)
self.file_contents = 'Slow load pending'
async_call(self.slow_load, self.slow_complete)
def on_button_clicked(self, widget):
print self.file_contents
def slow_complete(self, results, errors):
'''
'''
self.file_contents = results
self.button.set_label(self.file_contents)
self.button.show_all()
def slow_load(self):
'''
'''
time.sleep(5)
self.file_contents = "Slow load in progress..."
time.sleep(5)
return 'Slow load complete'
if __name__ == '__main__':
win = SlowLoad()
win.show_all()
#time.sleep(10)
Gtk.main()
附加说明,您必须先让另一个线程结束,然后其他线程才能正常终止,或者检查子线程中的file.lock。
编辑以评论:
最初我忘记了GObject.threads_init()
。显然,当按钮触发时,它为我初始化了线程。这为我掩盖了错误。
通常流程是在内存中创建窗口,立即启动另一个线程,当线程完成后更新按钮。我什至在调用Gtk.main之前添加了额外的睡眠,以验证完整更新是否可以在绘制窗口之前运行。我也将其注释掉,以验证线程启动完全不会阻碍窗口绘制。