2016-12-29 90 views
0

正如有人誰是新的節目,我不斷地發現自己遇到了錯誤和問題,同時尋找答案和解決方案,我很少找出爲什麼是這樣的。這一次,它與Python 2.7上的Tkinter。 手頭的問題是每次按下我創建的「提交」按鈕時,GUI都會凍結。研究部門告訴我,這個問題是因爲沒有回調讓程序到達主循環。我面臨的問題是與GUI一起運行的程序是定時器上永無止境的自動化循環。我也在這個網站上搜索過,但是,像往常一樣,我只能得到答案,它說「這樣做,因爲我說它的工作原理」。作爲一個真正感興趣並試圖深入探究編程的輝煌黑洞的人,解釋爲什麼需要這樣做以及你如何得出這個結論對我來說是一個很大的幫助。我完全理解,編程是那些廣泛而又特別的東西之一,解釋會變得不同,有時候會有偏差,但是我發現很難從其他方面學習。當我點擊我的按鈕時,如何阻止我的Tkinter GUI凍結?

我的代碼到目前爲止的簡化版本如下: (我知道簡化的代碼在本網站上不是首選,但我沒有辦法在沒有編寫代碼的情況下將代碼轉移到任何其他計算機所有下來,在這裏鍵入它。我知道你們會在我喊它以後。因此,對於這一點,我很抱歉。)

import os 
import time 
from datetime import datetime 
import shutil 
from Tkinter import * 

root=Tk() 
root.title("Automation") 
root.config(bg="black") 
root.geometry("500x500") 

def submit(): 
    input=e1.get() 
    #the input is a limit set for a variable in the timer that when 
    #it hits that limit, it jumps to the 400 lines of code 
    def Timer(): 
     <timer code> 
    <400 lines of code that has been tested to work 100%> 
    Timer() 

b1=Button(root, command=submit) 
button.grid(row=0, column =0) 
e1=Entry(root, width=50) 
e1.grid(row=0, column=1) 

mainloop() 

而且,我覺得很難發現和明確的信息,如果沒有它說GUI的GUI程序「嘿...只是這樣做,因爲我這麼說」,並鏈接到一些研究/參考材料將不勝感激。

像往常一樣,我非常感謝所有這一切都在本網站和所有的智能大大個人,使人們認爲它是地方提供的幫助。謝謝你們!

+1

問題出在''。這段代碼是否有一個大循環?如果沒有,是否有可能將這些代碼分成幾個毫秒或更少的塊來運行? –

+1

你讀過以下博客文章嗎?它很好地解釋了發生的事情:http://stupidpythonideas.blogspot.com/2013/10/why-your-gui-app-freezes.html –

回答

0

您Tk的GUI凍結的原因是因爲你有1個線程運行的一切。 mainloop受到submit函數調用的影響,該函數調用必須花費很長時間,因此當您單擊按鈕時,您可能會在Tk窗口中看到「Not Responding」(未響應)。爲了解決這個問題,你需要生成一個單獨的線程來submit在運行,這樣可以mainloop繼續做這件事,並凍結保持你的Tk的窗口。

這是使用threading完成。相反,您的按鈕直接調用submit,有按鈕調用啓動一個新線程,然後開始submit的功能。然後創建另一個函數來檢查線程的狀態。您也可以添加一個狀態欄

import os 
import time 
from datetime import datetime 
import shutil 
import threading 
from Tkinter import * 
import ttk 

def submit(): 
    time.sleep(5) # put your stuff here 


def start_submit_thread(event): 
    global submit_thread 
    submit_thread = threading.Thread(target=submit) 
    submit_thread.daemon = True 
    progressbar.start() 
    submit_thread.start() 
    root.after(20, check_submit_thread) 

def check_submit_thread(): 
    if submit_thread.is_alive(): 
     root.after(20, check_submit_thread) 
    else: 
     progressbar.stop() 

root = Tk() 
frame = ttk.Frame(root) 
frame.pack() 
progressbar = ttk.Progressbar(frame, mode='indeterminate') 
progressbar.grid(column=1, row=0, sticky=W) 

ttk.Button(frame, text="Check", 
     command=lambda:start_submit_thread(None)).grid(column=0, row=1,sticky=E) 
root.mainloop() 
相關問題