2017-08-08 85 views
1

我想創建一個不確定的進度條在python 3在新的頂級窗口的某些過程,然後啓動該進程的線程。我想要的是進度條啓動並且線程也在後臺啓動,一旦線程完成執行,一些消息顯示任務已完成。如何創建一個不確定的進度,並在後臺啓動一個線程,並在Python中完成線程後再次執行一些操作

代碼:

class myThread(threading.Thread): 
    def __init__(self, threadID): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 


    def run(self): 
     print("Starting the thread") 
     func() 
     print("Ending the thread") 

def func(): 
    some task 

... 
new_top = Toplevel() 
new_top.title("New Top Level") 
new_top.geometry("400x170") 

label = Label(new_top, text='Doing some work', justify=CENTER, bg="#CBFDCB").place(x=43,y=30) 

progress_bar = ttk.Progressbar(new_top, orient="horizontal", mode="indeterminate", takefocus=True, length=320) 
progress_bar.place(x=40, y=80) 
progress_bar.start() 

thread1 = myThread(1) 
thread1.start() 
thread1.join() 

... 

執行後的線程操作

我的問題是什麼,帶標籤和進度條的頂層窗口,如果thread1.join()被調用永遠不會出現,如果我跳過此部分,那麼操作後線程執行不會運行

回答

0

用Tkinter對線程進行線程化可能有點棘手。這裏有一些代碼可以實現你想要的功能。我的第一個版本無法正常工作,因爲我試圖從線程的.run方法中銷燬Tkinter窗口。這不起作用:窗口關閉,但root.destroy調用後.run方法沒有進展。所以現在我們有一個函數每隔100毫秒檢查一次線程是否仍然活着,如果它沒有活動,我們關閉Tkinter窗口。

import threading 
import tkinter as tk 
from tkinter import ttk 
from time import sleep 

class myThread(threading.Thread): 
    def __init__(self, threadID): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 

    def run(self): 
     print("Starting the thread") 
     func() 
     print("Ending the thread") 

def func(): 
    for i in range(10): 
     print(i) 
     sleep(1) 

def check_thread(th): 
    if not th.isAlive(): 
     root.destroy() 
    root.after(100, check_thread, th) 

root = tk.Tk() 
root.title("New Top Level") 
root.geometry("400x170") 

tk.Label(root, text='Doing some work', justify=tk.CENTER, bg="#CBFDCB").place(x=43, y=30) 
progress_bar = ttk.Progressbar(root, orient="horizontal", 
    mode="indeterminate", takefocus=True, length=320) 
progress_bar.place(x=40, y=80) 
progress_bar.start() 

thread1 = myThread(1) 
thread1.start() 
root.after(100, check_thread, thread1) 
root.mainloop() 

print("Doing post-thread stuff") 
0

TKinter通過使用無限主循環來等待和處理事件 - 截取按下按鈕,重繪元素等(看看here瞭解更多信息)。

當你調用join()時,你強制你的主線程(在其中運行tkinter)等待,直到你剛剛開始的線程完成執行,然後再繼續,因此它無法繪製帶有進度條的頂級窗口。因此,這不是一個真正的選擇。

另一方面,您需要知道您的子線程何時完成執行。您可以使用mythread.isAlive()來檢查線程是否仍然存在,但是不能在循環中執行它,因爲它會再次停止執行tkinter的主循環,從而繪製界面。我建議尋找at the answer here來處理這個問題。

相關問題