首页 > 解决方案 > 无法让 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()

标签: pythontkinter

解决方案


这是您当前在代码中的内容:

你设置self.espconnecting = False

你打电话_connect_esp()

调用_show_conn_progress()

设置self.espconnecting = True并启动进度条self.sp_pbar.start()

然后打电话_update_conn_progress()

它检查 的值self.espconnecting。如果self.espconnectingTrue(目前是)连接继续,进度条按预期滚动。如果进度条self.espconnecting停止Falseself.sp_pbar.stop()

.after()可以在 500 毫秒内回调之前,将 Control 传递回_connect_espwhich 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()

推荐阅读