2016-12-29 16 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プログラムを "ちょっと...ちょうど私がそう言ったのでこれを行う"と言うことなく、いくつかの研究/参考資料へのリンクが大いに感謝されるだろう。

いつものように、私はこのサイト全体を通して提供されているすべての助けと、それが存在する場所にする非常にインテリジェントな個人すべてに感謝します。皆さん、ありがとうございました!

+1

問題は「」です。このコードブロックに大きなループがありますか?もしそうでなければ、そのコードを実行するのに数百ミリ秒かそれ以下の時間を要するチャンクに分解することは可能でしょうか? –

+1

次のブログ記事を読んでいますか?何が起きているのかを説明するのはうまくいく:http://stupidpythonideas.blogspot.com/2013/10/why-your-gui-app-freezes.html –

答えて

0

Tk GUIがフリーズするのは、すべてが1つのスレッドで実行されているからです。 mainloopは、submit関数呼び出しによって返されます。この呼び出しは、「長い時間がかかる」必要があります。そのため、ボタンをクリックすると、Tkウィンドウに「応答していません」と表示されることがあります。これを修正するには、submitを実行する別のスレッドを作成する必要があります。そのため、mainloopはそれを維持してTkウィンドウがフリーズすることを防ぐことができます。

これはthreadingを使用して行われます。 submitを直接呼び出すボタンの代わりに、ボタンを押して新しいスレッドを開始する関数を呼び出すと、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() 
関連する問題