使用python3和gi.repository,我希望有一个带有Gtk.Button的Gtk.HeaderBar,只要你点击它就会被Gtk.Spinner取代。计算完成后,按钮应再次出现。
以下是我认为它应该如何工作的示例,但Gtk.Spinner仅在计算后(在此示例中为sleep)显示很短的时间。如何实现微调器显示整个计算(或睡眠)?
from gi.repository import Gtk
import time
class window:
def __init__(self):
self.w = Gtk.Window()
self.button = Gtk.Button('x')
self.button.connect('clicked', self.on_button_clicked)
self.spinner = Gtk.Spinner()
self.hb = Gtk.HeaderBar()
self.hb.props.show_close_button = True
self.hb.pack_start(self.button)
self.w.set_titlebar(self.hb)
self.w.connect('delete-event', Gtk.main_quit)
self.w.show_all()
def on_button_clicked(self, widget):
self.button.hide()
self.hb.pack_start(self.spinner)
self.spinner.show()
self.spinner.start()
time.sleep(5)
self.spinner.stop()
self.hb.remove(self.spinner)
self.button.show()
if __name__ == '__main__':
w = window()
Gtk.main()
答案 0 :(得分:1)
问题是time.sleep():它是一个阻塞函数。
def on_button_clicked(self, widget):
self.button.hide()
self.hb.pack_start(self.spinner)
self.spinner.show()
self.spinner.start()
t = time.time()
while time.time() - t < 5:
Gtk.main_iteration()
self.spinner.stop()
self.hb.remove(self.spinner)
self.button.show()
我认为这就是你所期望的。
编辑:你可以在循环中放入time.sleep(.1)来保存cpu,但不要忘记Gtk.main_iteration():这是从循环到主循环退出的函数(显示微调器,进度条等)。
答案 1 :(得分:1)
GTK +是一个事件驱动的系统,其中主循环应该可以自由更新UI,所有需要时间的东西(如从文件读取,建立网络连接,长时间计算)都应该异步发生。
在你的情况下,这看起来像这样:
def on_button_clicked(self, widget):
self.button.hide()
self.spinner.show()
self.spinner.start()
GLib.timeout_add_seconds (5, self.processing_finished)
def processing_finished(self):
self.spinner.stop()
self.spinner.hide()
self.button.show()
请注意,我删除了这个包并删除了来电:在__init__()
中执行此操作。你也希望from gi.repository import GLib
在那里。
这样主循环就可以随意更新UI。如果你真的想使用像sleep()这样的阻塞调用,那么你需要在另一个线程中执行此操作,但我的建议是使用像timeout_add_seconds()
调用那样不同步的库。