python - 无法让 ttk.Progressbar 正确启动
问题描述
我无法让ttk.Progressbar
小部件工作。我可以知道是什么问题以及如何解决吗?
我知道 Progressbar 小部件可以正常工作;当我注释掉 self.sp_pbar.stop()
进度条运行时,这发生在time.sleep(5)
完成后,这不是所需的行为。
import tkinter as tk
import tkinter.ttk as ttk
import time
class App(ttk.Frame):
def __init__( self, master=None, *args, **kw ):
super().__init__( master,style='App.TFrame')
self.master = master
self.espconnecting = False
self._set_style()
self._create_widgets()
def _set_style( self ):
print( '\ndef _set_style( self ):' )
self.style = ttk.Style()
self.style.configure( 'App.TFrame', background='pink')
self.style.configure( 'sp.TFrame', background='light green')
def _create_widgets( self ):
print( '\ndef _create_widgets( self ):' )
self.sp_frame = ttk.Frame( self, style='sp.TFrame' )
self.sp_frame.grid(row=0, column=0)
#self.sp_frame widgets
self.sp_label1 = ttk.Label( self.sp_frame, text='SP(s):')
self.sp_label2 = ttk.Label( self.sp_frame, text='ESP(s):')
self.sp_label3 = ttk.Label( self.sp_frame, )
self.sp_combox = ttk.Combobox( self.sp_frame, state="readonly",
values=['a','b','c'] )
self.sp_combox.bind('<<ComboboxSelected>>', self._connect_esp)
self.sp_pbar = ttk.Progressbar( self.sp_frame, length=200,
mode='indeterminate',
orient=tk.HORIZONTAL, )
self.sp_label1.grid( row=0, column=0 )
self.sp_combox.grid( row=0, column=1, padx=[10,0] )
self.sp_pbar.grid( row=1, column=0, columnspan=2, sticky='ew' )
self.sp_label2.grid( row=2, column=0)
self.sp_label3.grid( row=2, column=1)
def _connect_esp( self, event=None):
print( '\ndef connect_esp( self, event=None ):' )
self._show_conn_progress()
print("START Connection")
time.sleep(5) # The code is running a function here which can take some time.
print("END Connection")
self.espconnecting = False
def _show_conn_progress( self ):
print( '\ndef _show_conn_progress( self ):' )
self.espconnecting = True
self.sp_label3['text']='Connecting.....'
self.sp_label3.update_idletasks()
self.sp_pbar.start()
self._update_conn_progress()
def _update_conn_progress( self ):
print( '\ndef _update_conn_progress( self ):' )
if not self.espconnecting:
print('connected')
self.sp_pbar.stop()
self.sp_label3['text']='Connected'
else:
print('connecting')
self.sp_pbar.update_idletasks()
self.after(500, self._update_conn_progress) # Call this method after 500 ms.
def main():
root = tk.Tk()
root.geometry('300x100+0+24')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
app = App( root )
app.grid(row=0, column=0, sticky='nsew')
root.mainloop()
if __name__ == '__main__':
main()
解决方案
这是您当前在代码中的内容:
你设置self.espconnecting = False
你打电话_connect_esp()
调用_show_conn_progress()
设置self.espconnecting = True
并启动进度条self.sp_pbar.start()
然后打电话_update_conn_progress()
它检查 的值self.espconnecting
。如果self.espconnecting
是True
(目前是)连接继续,进度条按预期滚动。如果进度条self.espconnecting
停止False
self.sp_pbar.stop()
在.after()
可以在 500 毫秒内回调之前,将 Control 传递回_connect_esp
which sets self.espconnecting = False
。然后.after()
调用_update_conn_progress()
这是为了保持酒吧滚动,
但是(这是您的问题): 的最后一个值是self.espconnecting
多少?=False
因此,控制分支到self.sp_pbar.stop()
,这会停止进度条。这就是为什么当您注释该行时,您的代码按预期工作,因为即使控制分支在那里,也不会阻止进度条工作。
解决方案
不要设置self.espconnecting = False
,_connect_esp()
因为之前.after()
让它在 500 毫秒内回调,控制将被传递回阻止进度条工作的_connect_esp()
集合。self.espconnecting = False
这意味着一旦开始,您必须找到另一种“结束连接”的方法。
注意:我真的没有看到time.sleep(5)
代码中的需要。
这是解决它的一种可能方法:
...
def __init__( self, master=None, *args, **kw ):
super().__init__( master,style='App.TFrame')
self.master = master
self.espconnecting = False
self.count=0
self._set_style()
self._create_widgets()
def _set_style( self ):
print( '\ndef _set_style( self ):' )
self.style = ttk.Style()
self.style.configure( 'App.TFrame', background='pink')
self.style.configure( 'sp.TFrame', background='light green')
def _create_widgets( self ):
print( '\ndef _create_widgets( self ):' )
self.sp_frame = ttk.Frame( self, style='sp.TFrame' )
self.sp_frame.grid(row=0, column=0)
#self.sp_frame widgets
self.sp_label1 = ttk.Label( self.sp_frame, text='SP(s):')
self.sp_label2 = ttk.Label( self.sp_frame, text='ESP(s):')
self.sp_label3 = ttk.Label( self.sp_frame, )
self.sp_combox = ttk.Combobox( self.sp_frame, state="readonly",
values=['a','b','c'] )
self.sp_combox.bind('<<ComboboxSelected>>', self._connect_esp)
self.sp_pbar = ttk.Progressbar( self.sp_frame, length=200,
mode='indeterminate',
orient=tk.HORIZONTAL, )
self.sp_label1.grid( row=0, column=0 )
self.sp_combox.grid( row=0, column=1, padx=[10,0] )
self.sp_pbar.grid( row=1, column=0, columnspan=2, sticky='ew' )
self.sp_label2.grid( row=2, column=0)
self.sp_label3.grid( row=2, column=1)
def _connect_esp( self, event=None):
print( '\ndef connect_esp( self, event=None ):' )
self._show_conn_progress()
print("START Connection")
time.sleep(5)
def end_connection(self):
print("END Connection")
self.espconnecting = False
def _show_conn_progress( self ):
print( '\ndef _show_conn_progress( self ):' )
self.espconnecting = True
self.sp_label3['text']='Connecting.....'
self.sp_label3.update_idletasks()
self.sp_pbar.start()
self._update_conn_progress()
def _update_conn_progress( self ):
print( '\ndef _update_conn_progress( self ):' )
if not self.espconnecting:
print('connected')
self.sp_pbar.stop()
self.sp_label3['text']='Connected'
else:
print('connecting')
#self.sp_pbar.update_idletasks()
self.after(500, self._update_conn_progress) # Call this method after 500 ms.
self.count=self.count + 1
if self.count==10:
self.end_connection()
def main():
root = tk.Tk()
root.geometry('300x100+0+24')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
app = App( root )
app.grid(row=0, column=0, sticky='nsew')
root.mainloop()
if __name__ == '__main__':
main()
推荐阅读
- r - 为什么我收到错误:当我从 ggseas 包运行命令 ggsdc 时,“ts”对象必须有一个或多个观察结果?
- sql - Postgres:group by内的不同聚合
- sql-server - 在日期维度表的 while 循环条件内使用 DATEDIFF 添加 30 天的存储过程
- android - 自定义叠加视图中的透明背景不起作用
- java - 确定板上的两个方格是否由相同的方格连续/连接 turn()
- javascript - 需要帮助将 py 转换为 js
- javascript - 如何在移动设备上制作不可点击的电子邮件地址(android)
- typescript - 使用 typescript 反应原生 - 如何使用来自 @react-navigation/native 的 useRoute 和 typescript
- django - 无法在 nginx docker 容器上使用 http2
- firefox - 如何在 Firefox 跟踪中添加特定域/站点作为例外?它变灰了