我一直试图将此问题排序数小时,在网上搜索并阅读文档并没有帮助。我正在尝试在单独的线程中执行长时间运行的任务,并在UI中的进度条中显示进度。新线程已启动,但在主循环退出之前没有给出任何时间,我在Gdk.threads_init()
之前调用Gtk.main
并且我已使用Gdk.threads_enter()
和Gdk.threads_leave()
包围了UI调用。
下面的代码重现了这个问题,单击“开始”按钮没有任何效果,但是一旦窗口关闭并且主循环退出,我看到第二个线程正在工作(即我看到打印语句相隔半秒)
class App(Gtk.Window):
def __init__(self):
super(App, self).__init__()
self.connect("destroy", self.on_destroy)
self.layout = Gtk.VBox()
self.progress = Gtk.ProgressBar()
self.layout.pack_start(self.progress, False, False, 0)
self.set_size_request(100,100)
self.go_button = Gtk.Button("Start")
self.go_button.connect("clicked", self.do_work_subclass)
self.layout.pack_start(self.go_button, False, False, 0)
self.add(self.layout)
self.show_all()
def on_destroy(widget, event):
Gtk.main_quit()
def do_work(self, widget):
def worker_thread():
so_far = 0
while so_far < 10:
time.sleep(0.5)
print("work so far: %s" % so_far)
Gdk.threads_enter()
try:
if so_far > 0:
self.progress.set_fraction(so_far / 10.0)
finally:
Gdk.threads_leave()
so_far += 1
threading.Thread(target=worker_thread).start()
if __name__ == "__main__":
app = App()
Gdk.threads_init()
Gdk.threads_enter()
Gtk.main()
Gdk.threads_leave()
这可能与我使用Gtk3的事实有关吗?
答案 0 :(得分:4)
在发布问题之前花了好几个小时试图找到答案,我在发布后的几分钟内找到了答案。事实证明(从here)您需要致电GLib.threads_init()
的GTK3,代码在调用from gi.repository import GLib
之前使用初始GLib.threads_init()
和Gtk.main()
,所以代码的工作版本如下所示:
from gi.repository import Gtk,Gdk, GLib
import threading
import time
class App(Gtk.Window):
def __init__(self):
super(App, self).__init__()
self.connect("destroy", self.on_destroy)
self.layout = Gtk.VBox()
self.progress = Gtk.ProgressBar()
self.layout.pack_start(self.progress, False, False, 0)
self.set_size_request(100,100)
self.go_button = Gtk.Button("Start")
self.go_button.connect("clicked", self.do_work)
self.layout.pack_start(self.go_button, False, False, 0)
self.add(self.layout)
self.show_all()
def on_destroy(widget, event):
Gtk.main_quit()
def do_work(self, widget):
def worker_thread():
so_far = 0
while so_far < 10:
time.sleep(0.5)
print("work so far: %s" % so_far)
Gdk.threads_enter()
try:
if so_far > 0:
self.progress.set_fraction(so_far / 10.0)
finally:
Gdk.threads_leave()
so_far += 1
threading.Thread(target=worker_thread).start()
if __name__ == "__main__":
app = App()
GLib.threads_init()
Gdk.threads_init()
Gdk.threads_enter()
Gtk.main()
Gdk.threads_leave()