2016-07-26 8 views
0

私はターニングホイールのアニメーションを作成しようとしていますが、whileループで少し遅れて、毎回ホイールを更新したいと考えています。私は、tkinterの "after"関数とpythonの "sleep"関数の両方を試しましたが、衝突を起こすか、または終了して、ホイールが回転している間に実際のアニメーションが表示されません。whileループはtkinterアニメーションでは機能しません

私は回し車用に作成された機能:

def turning(): 
    #initial wheel position 
    global position 
    pos(position) 

    #infinite loop turning the wheel 
    while(1): 
     root.after(1000, spin) 

def spin(): 
    global position 
    global speed 
    delspike() #delete current wheel 
    position += speed #calculate next position 
    if position > 360: 
     position -= 360 
    pos(position) #draw new wheel 

は、なぜこれが動作しませんか?

+0

ホイールを描画または再描画した後、 'root.update_idletasks()'を呼び出してみてください。 – martineau

+0

@Pythonista:いいえ、while whileループは解決策ではありません。まったく同じ悪い振る舞いをします。 –

答えて

0

afterはあなたがループに入れしようとしている関数内で使用されている:

def f(): 
    ... 
    root.after(1000, f) 

(1000これはプログラムは1秒ごとに操作を実行することを意味し、1秒で1000ミリ秒を意味します。 ) また、Tkinterで無限whileループ(while Truewhile 1など)を使用すると、ウィンドウが応答しないになることに注意してください。ここではこれについてたくさん議論しました。あなたがSOについて調べていれば、これを見つけることができます。

0

このコード:

while (1): 
    root.after(1000, spin) 

...は、1秒で実行するspin機能をスケジュールしようとしています。目を瞬く間に何千ものことをやろうとしています。 spinに1秒で実行するよう依頼していても、whileループ自体は可能な限り速く実行され、決して停止することはありません。最初のスピンの前に何十万ものスピンを予定しています。そして、それらはすべて1秒で動こうとするので、順番に走ります。

def spin(): 
    ... 
    root.after(1000, spin) 

はその後、あなたはあなたのプログラムの開始時に一度だけspinを呼び出し、それが無期限に実行されます。

アニメーションを行うための正しい方法は、1秒間に再び機能、スケジュール自体を持つことです。

+0

これは素晴らしい作品のおかげですごくうれしい – moonboon

0

私は多くの初心者が「よく分からない」ことが気づきましたが、whileループでtkinterをアニメーション化しようとしました。これは愚かな考えではないことが判明しました。私は最近、asyncioと3.5 async-await構文の新機能を使ってこの作業を行う方法を考え出しました。私はシンプルなアプリケーション用の汎用テンプレートも作りました。後のループを使うよりもこのスタイルが好きです。 3.5.2または3.6.0a3がインストールされている(またはいずれかをインストールしている)場合は、このコードを実行して自分のローテータをあなたのものに置き換えることができます。

import asyncio 
import tkinter as tk 


class App(tk.Tk): 

    def __init__(self, loop, interval=1/120): 
     super().__init__() 
     self.loop = loop 
     self.protocol("WM_DELETE_WINDOW", self.close) 
     self.tasks = [] 
     self.tasks.append(loop.create_task(
       self.rotator(1/60, 1))) 
     self.updater(interval) 

    async def rotator(self, interval, d_per_int): 
     canvas = tk.Canvas(self, height=600, width=600) 
     canvas.pack() 
     deg = 0 
     arc = canvas.create_arc(100, 100, 500, 500, 
           start=0, extent=deg, fill='blue') 
     while True: 
      await asyncio.sleep(interval) 
      deg = (deg + d_per_int) % 360 
      canvas.itemconfigure(arc, extent=deg) 

    def updater(self, interval): 
     self.update() 
     self.loop.call_later(interval, self.updater, interval) 

    def close(self): 
     for task in self.tasks: 
      task.cancel() 
     self.loop.stop() 
     self.destroy() 


loop = asyncio.get_event_loop() 
app = App(loop) 
loop.run_forever() 
loop.close() 
関連する問題