我正在使用PyGObject在Python中编写我的第一个GTK + 3应用程序。
我有一个任务,我希望用户点击“开始”按钮然后我想要更新一个带有倒计时的文本字段,显示" 3"," 2",& #34; 1"," Go!"在两者之间暂停。
如果在按钮回调方法中我在暂停之间更改文本,它只显示我学到的最后一个更改,因为窗口只在重新回到主循环时重绘。我的想法是,我需要强迫它重绘。
我发现了一些旧的PyGTK示例:
while Gtk.events_pending():
Gtk.main_iteration()
现在它有点工作,但它不会重新拉出未按下的按钮,直到显示2并且在不同的版本中它总是错过画出3.可能事件还没有待处理?我也不确定这是不是"正确的"做我想做的事情。我实际上有一堆线性任务需要在按下按钮后需要进行屏幕更新,这只是一个简单的例子。
以下是现在的代码:
from gi.repository import Gtk, GdkPixbuf, Gdk, GLib
import Image
import os, sys
import time
class GUI:
def __init__(self):
self.window=Gtk.Window()
self.window.set_title("Countdown")
self.window.set_border_width(10)
self.window.connect_after('destroy', self.destroy)
# main container of projct
self.main_box=Gtk.VBox()
self.main_box.set_spacing(5)
# countdown label
self.countdown_label = Gtk.Label()
# start button
self.start_button=Gtk.Button("Start!")
# add the elements to the window
self.window.add(self.main_box)
self.main_box.pack_start(self.countdown_label, False, False, 0)
self.main_box.pack_start(self.start_button, False, False, 0)
# connect buttons
self.start_button.connect_after('clicked', self.start_clicked)
self.window.show_all()
def start_clicked(self, button):
# start the countdown
count=3
while count > 0:
self.countdown(count)
count = count - 1
while Gtk.events_pending():
Gtk.main_iteration()
time.sleep(2)
self.countdown_label.set_text("Go!")
def countdown(self, count):
self.countdown_label.set_text(str(count))
print count
return
def destroy(window, self):
Gtk.main_quit()
def main():
app=GUI()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
答案 0 :(得分:2)
在GTK +编程方面,需要使用Gtk.events_pending()和Gtk.main_iteration()通常是一个红旗。修复这个特定的例子,可以使用不阻塞主循环的异步超时[1]:
def start_clicked(self, button):
self.countdown(3)
def countdown(self, count):
if count > 0:
self.countdown_label.set_text(str(count))
# Manually re-add this callback with a decremented count.
GLib.timeout_add_seconds(2, self.countdown, count - 1)
else:
self.countdown_label.set_text("Go!")
# Return False so the callback is not called repeatedly
# as we manually re-added the callback ourselves above.
return False
在现实世界中,正如“一堆需要进行的线性任务”所述,答案取决于任务的类型。可能阻止UI的IO绑定任务可以使用Gio库来维护UI响应[2]。对于阻止UI的CPU绑定任务,Python线程[3]可以与使用Gdk.threads_add_idle或Gdk.threads_add_timeout [4]安排的UI更新回调结合使用。
另见: