Python,Gtk3:如何使进度条在其他内容 运行 时闪烁
Python,Gtk3: How to make the Progress bar pulsing while other stuffs are running
基于 类,我有 window,其中包含 button
和 progressbar
,只要单击按钮,就会发生两件事:
1 - should entried value from dialog pass to class ABCD
2 - While our class ABCD()
do his stuff, should our progressbar do regular pulsing untill the class ABCD() finish process.
所以问题是进度条只跳动一次,然后卡在那里直到 class ABCD() 完成,然后它开始有规律地跳动。
这是我的尝试:
import gi,time
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject
class DialogExample(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "My Dialog", parent, 0,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK))
self.set_default_size(150, 100)
self.Myinput = Gtk.Entry()
box = self.get_content_area()
box.add(self.Myinput)
self.show_all()
class DialogWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Dialog Example")
self.set_border_width(6)
Hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.add(Hbox)
self.button = Gtk.Button("Open dialog")
self.button.connect("clicked", self.on_button_clicked)
Hbox.pack_start(self.button, True, True, 0)
self.progressbar = Gtk.ProgressBar()
Hbox.pack_start(self.progressbar, True, True, 0)
#~~~~~~ Progress Bar
def on_timeout(self, user_data):
"""
Update value on the progress bar
"""
if self.activity_mode:
self.progressbar.pulse()
else:
new_value = self.progressbar.get_fraction() + 0.01
if new_value > 1:
new_value = 0
self.progressbar.set_fraction(new_value)
# As this is a timeout function, return True so that it
# continues to get called
return True
def on_button_clicked(self, widget):
dialog = DialogExample(self)
response = dialog.run()
if response == Gtk.ResponseType.OK:
variable = dialog.Myinput.get_text()
print("start")
dialog.destroy()
#ProgressBar time function
self.timeout_id = GObject.timeout_add(50, self.on_timeout, None)
self.activity_mode = False
self.progressbar.pulse()
#this for Updating the Windows and make the progressbar pulsing while waiting
# the class ABCD finish his stuff, finally should stop pulsing.
while Gtk.events_pending():
Gtk.main_iteration_do(False)
passing_instance = ABCD(variable)
class ABCD(object):
def __init__(self,value_of_dialog):
self.get_value = value_of_dialog
self.for_add = "______ add was done"
self.final_value = self.get_value+self.for_add
time.sleep(10)
print("gonna be finished")
print(self.final_value)
win = DialogWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
正如我们在这里看到的,我已经尝试在这部分代码中生成脉冲并刷新 windows
self.timeout_id = GObject.timeout_add(50, self.on_timeout, None)
self.activity_mode = False
self.progressbar.pulse()
#this for Updating the Windows and make the progressbar pulsing while waiting
# the class ABCD finish his stuff, finally should stop pulsing.
while Gtk.events_pending():
Gtk.main_iteration_do(False)
Otherwise because in my class ABCD()
i have time.sleep(10)
should
the progress bar pulse only for that time 10 seconds later only then
stop.
这段代码应该如何编写,我需要有人向我提供正确的代码,并提供一些解释。
使用 sleep
来模拟时间流逝的问题是 sleep
将停止线程中发生的所有事情,在这种情况下阻止线程到达 Gtk.main()
使您的进度条脉动或更新所必需的。
因此,为了正确执行此操作,有 2 个选项:
运行 ABCD
在单独的线程中以便主线程可以到达 Gtk.main()
。这将确保进度条按预期移动。一个简单的例子如下所示:
self.abcd_thread = ABCD(variable)
self.abcd_thread.start()
class ABCD(Thread):
def __init__(self, value_of_dialog):
super(ABCD, self).__init__()
self.get_value = value_of_dialog
self.for_add = "______ add was done"
self.final_value = self.get_value+self.for_add
def run(self):
print "Starting " + self.name
time.sleep(10)
print("gonna be finished")
print(self.final_value)
print "Exiting " + self.name
使用这个时你可以使用self.abcd_thread.isAlive()
查看线程是否还在计算东西。 return 信息的获取方式在很大程度上取决于线程中放置的作业。
将 time.sleep
替换为以下片段:
now = time.time()
while time.time() - now < 10:
# Insert any code here
Gtk.main_iteration_do(False)
这仍然会模拟 ABCD
做 10 秒的事情,但是因为我们在循环的每次迭代中调用 Gtk.main_iteration_do(False)
GTK 能够在循环期间更新界面。
一般来说,第二种选择是最简单的,因为无论您在做什么,它只涉及进行 Gtk.main_iteration_do(False)
调用。另一方面,第一个选项在处理添加 Gtk 调用不容易适应的复杂计算时更有用。
基于 类,我有 window,其中包含 button
和 progressbar
,只要单击按钮,就会发生两件事:
1 - should entried value from dialog pass to
class ABCD
2 - While our class
ABCD()
do his stuff, should our progressbar do regular pulsing untill the class ABCD() finish process.
所以问题是进度条只跳动一次,然后卡在那里直到 class ABCD() 完成,然后它开始有规律地跳动。
这是我的尝试:
import gi,time
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject
class DialogExample(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "My Dialog", parent, 0,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK))
self.set_default_size(150, 100)
self.Myinput = Gtk.Entry()
box = self.get_content_area()
box.add(self.Myinput)
self.show_all()
class DialogWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Dialog Example")
self.set_border_width(6)
Hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.add(Hbox)
self.button = Gtk.Button("Open dialog")
self.button.connect("clicked", self.on_button_clicked)
Hbox.pack_start(self.button, True, True, 0)
self.progressbar = Gtk.ProgressBar()
Hbox.pack_start(self.progressbar, True, True, 0)
#~~~~~~ Progress Bar
def on_timeout(self, user_data):
"""
Update value on the progress bar
"""
if self.activity_mode:
self.progressbar.pulse()
else:
new_value = self.progressbar.get_fraction() + 0.01
if new_value > 1:
new_value = 0
self.progressbar.set_fraction(new_value)
# As this is a timeout function, return True so that it
# continues to get called
return True
def on_button_clicked(self, widget):
dialog = DialogExample(self)
response = dialog.run()
if response == Gtk.ResponseType.OK:
variable = dialog.Myinput.get_text()
print("start")
dialog.destroy()
#ProgressBar time function
self.timeout_id = GObject.timeout_add(50, self.on_timeout, None)
self.activity_mode = False
self.progressbar.pulse()
#this for Updating the Windows and make the progressbar pulsing while waiting
# the class ABCD finish his stuff, finally should stop pulsing.
while Gtk.events_pending():
Gtk.main_iteration_do(False)
passing_instance = ABCD(variable)
class ABCD(object):
def __init__(self,value_of_dialog):
self.get_value = value_of_dialog
self.for_add = "______ add was done"
self.final_value = self.get_value+self.for_add
time.sleep(10)
print("gonna be finished")
print(self.final_value)
win = DialogWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
正如我们在这里看到的,我已经尝试在这部分代码中生成脉冲并刷新 windows
self.timeout_id = GObject.timeout_add(50, self.on_timeout, None)
self.activity_mode = False
self.progressbar.pulse()
#this for Updating the Windows and make the progressbar pulsing while waiting
# the class ABCD finish his stuff, finally should stop pulsing.
while Gtk.events_pending():
Gtk.main_iteration_do(False)
Otherwise because in
my class ABCD()
i havetime.sleep(10)
should the progress bar pulse only for that time 10 seconds later only then stop.
这段代码应该如何编写,我需要有人向我提供正确的代码,并提供一些解释。
使用 sleep
来模拟时间流逝的问题是 sleep
将停止线程中发生的所有事情,在这种情况下阻止线程到达 Gtk.main()
使您的进度条脉动或更新所必需的。
因此,为了正确执行此操作,有 2 个选项:
运行
ABCD
在单独的线程中以便主线程可以到达Gtk.main()
。这将确保进度条按预期移动。一个简单的例子如下所示:self.abcd_thread = ABCD(variable) self.abcd_thread.start() class ABCD(Thread): def __init__(self, value_of_dialog): super(ABCD, self).__init__() self.get_value = value_of_dialog self.for_add = "______ add was done" self.final_value = self.get_value+self.for_add def run(self): print "Starting " + self.name time.sleep(10) print("gonna be finished") print(self.final_value) print "Exiting " + self.name
使用这个时你可以使用
self.abcd_thread.isAlive()
查看线程是否还在计算东西。 return 信息的获取方式在很大程度上取决于线程中放置的作业。将
time.sleep
替换为以下片段:now = time.time() while time.time() - now < 10: # Insert any code here Gtk.main_iteration_do(False)
这仍然会模拟
ABCD
做 10 秒的事情,但是因为我们在循环的每次迭代中调用Gtk.main_iteration_do(False)
GTK 能够在循环期间更新界面。
一般来说,第二种选择是最简单的,因为无论您在做什么,它只涉及进行 Gtk.main_iteration_do(False)
调用。另一方面,第一个选项在处理添加 Gtk 调用不容易适应的复杂计算时更有用。