将进度条绑定到线程

我有一些代码通过 telnet 会话将一些代码推送到机器上。在此期间(大约 30 秒),GUI (tkinter) 挂起,似乎程序崩溃了。为了解决这个问题,我想使用进度条。因此,按下“发送”按钮后,它会打开一个新屏幕。到现在为止还挺好。现在,我希望进度条在 telnet 脚本完成后停止。所以我研究了一下,我认为我需要使用(多)线程。一旦 telnetthread 完成,progressbarthread 应该停止,我再次看到主屏幕。


这是迄今为止的脚本...


from tkinter import Button, Tk, HORIZONTAL

import time

from tkinter.ttk import Progressbar

import threading




class main(Tk):


    def __init__(self):

        super().__init__()

        self.btn = Button(self, text='Run', command=self.pb)

        self.btn.grid(row=0,column=0)


    def pb(self):

        def real_pb():

            window = tk.Toplevel(root)

            window.progress = Progressbar(window, orient=HORIZONTAL,length=100,  mode='indeterminate')

            window.progress.grid(row=1,column=0)

            window.progress.start()


            time.sleep(10)#to be changed to thread of telnet session//dummyscript


            window.progress.stop()

            window.progress.grid_forget()

            window.destroy()

            self.btn['state']='normal'


        self.btn['state']='disabled'

        threading.Thread(target=real_pb).start()


    def dummyscript():

        time.sleep(10)

        print("slept")


root = main()

root.mainloop()

如何更改time.sleepdummyscript 的长度?


郎朗坤
浏览 143回答 1
1回答

慕侠2389804

首先,Tkinter 不支持多线程,所以所有关于 GUI 的代码都应该在主线程中。所以无法在real_pb().只要进程正在运行,我会做的是使用一个threading.Event在进程完成时将设置的对象。在 Tkinter mainloop 内部,我会定期轮询 Event 以了解进程是否完成:from tkinter import Button, Tk, HORIZONTAL, Toplevelimport timefrom tkinter.ttk import Progressbarimport threadingclass Main(Tk):    def __init__(self):        super().__init__()        self.btn = Button(self, text='Run', command=self.pb)        self.btn.grid(row=0,column=0)        self.finished = threading.Event()  # event used to know if the process is finished    def pb(self):        def check_if_finished():            if self.finished.is_set():                # process is finished, destroy toplevel                window.destroy()                self.btn['state']='normal'            else:                self.after(1000, check_if_finished)        window = Toplevel(root)        window.progress = Progressbar(window, orient=HORIZONTAL,length=100,  mode='indeterminate')        window.progress.grid(row=1,column=0)        window.progress.start()        self.btn['state']='disabled'        threading.Thread(target=self.dummyscript).start()        self.after(1000, check_if_finished) # check every second if the process is finished    def dummyscript(self):        self.finished.clear()  # unset the event        time.sleep(10)         # execute script        print("slept")        self.finished.set()    # set the eventroot = Main()root.mainloop()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python