2012-03-19 11 views
6

「フィード」を停止する際に問題が発生しています。 cancel引数はafterメソッドに影響を与えていないようです。 「フィード停止」はコンソールに印刷されますが、機能後にtkinterを停止するにはどうすればよいですか?

フィードを開始するボタンとフィードを停止するボタンがあるとします。出力付き

from Tkinter import Tk, Button 
import random 

    def goodbye_world(): 
     print "Stopping Feed" 
     button.configure(text = "Start Feed", command=hello_world) 
     print_sleep(True) 

    def hello_world(): 
     print "Starting Feed" 
     button.configure(text = "Stop Feed", command=goodbye_world) 
     print_sleep() 

    def print_sleep(cancel=False): 
     if cancel==False: 
      foo = random.randint(4000,7500) 
      print "Sleeping", foo 
      root.after(foo,print_sleep) 
     else: 
      print "Feed Stopped" 


    root = Tk() 
    button = Button(root, text="Start Feed", command=hello_world) 

    button.pack() 


    root.mainloop() 

:あなたはroot.after(...)を呼び出すと

Starting Feed 
Sleeping 4195 
Sleeping 4634 
Sleeping 6591 
Sleeping 7074 
Stopping Feed 
Sleeping 4908 
Feed Stopped 
Sleeping 6892 
Sleeping 5605 
+0

私はtkinterの仕組みについて完全にはわかっていませんが、これはスレッドの問題のようです。 a(スレッドセーフ)グローバルをキャンセルすると、問題が解決されますか? – mklauber

+0

@mklauber:いいえ、スレッドの問題ではありません。 Tkinterはシングルスレッドです。 –

+0

@ブライアンオークリー:ありがとう。これが私がコメントとして投稿した理由です。私は確信が持てませんでしたので、私はその質問を提起したいと思いました。 – mklauber

答えて

13

print_sleepTrueと呼んでサイクルを停止しても、すでに待機中のジョブが起動しているという問題があります。停止ボタンを押しても、新しいジョブは起動されませんが、古いジョブはまだそこに残っていて、自身を呼び出すと、Falseになり、ループが続行されます。

保留中のジョブをキャンセルして実行しないようにする必要があります。たとえば:

def cancel(): 
    if self._job is not None: 
     root.after_cancel(self._job) 
     self._job = None 

def goodbye_world(): 
    print "Stopping Feed" 
    cancel() 
    button.configure(text = "Start Feed", command=hello_world) 

def hello_world(): 
    print "Starting Feed" 
    button.configure(text = "Stop Feed", command=goodbye_world) 
    print_sleep() 

def print_sleep(): 
    foo = random.randint(4000,7500) 
    print "Sleeping", foo 
    self._job = root.after(foo,print_sleep) 

注:あなたがそのようなアプリケーションオブジェクトのコンストラクタのように、どこかself._jobを初期化することを確認してください。

13

、それは識別子を返します。その識別子を追跡し(たとえば、インスタンス変数に格納する)、後でroot.after_cancel(after_id)と呼び出してキャンセルする必要があります。

関連する問題