2016-05-09 4 views
1

ここで私は関数saySomething()を繰り返し実行し続けたいが、終了ボタンを押すと終了する関数runStuffがあります。Kivyのwhileループを壊すには?

現在、終了ボタンの入力を許可せずにwhileループを実行しています。

def saySomething(): 
    ttsSpeak('Say this phrase') 

def runStuff(self): 
    while True: 
     if App.get_running_app().stop() != True: 
      saySomething() 
      time.sleep(2) 
     else: break 

def exit(self): 
    App.get_running_app().stop() 

class AudibleCoachApp(App): 
    def build(self): 
     layout = BoxLayout(padding=7, spacing=3, orientation='vertical') # set layout of the screen 
     btn1 = Button(text='Start it', size_hint=(1, .66)) # create a button instance 
     btn1.bind(on_press=runStuff) # binding the button with the function below 
     btn3 = Button(text='Exit', size_hint=(1, .17)) # create a button instance 
     btn3.bind(on_press=exit) # binding the button with the function below 
     layout.add_widget(btn1) # physically add the button onto the layout 
     layout.add_widget(btn2) # physically add the button onto the layout 
     layout.add_widget(btn3) # physically add the button onto the layout 

     return layout 

if __name__ == '__main__': 
    AudibleCoachApp().run() 
+0

whileループ条件で 'stop()'の代わりに本当に何を呼び出すのですか?あなたのアプリが止まっているかどうかを知らせる何かを探しているようですね。 –

+0

あなたの質問についてはあまり確かではありません。 exitボタンが押されていない限り、runStuff()がsaySomething()を呼び出し続けるようにします。 exitボタンを押すと、exit関数を実行します。 – KubiK888

+0

さて、まあ、別の場所で 'stop()'と呼んでください。あなたは、それぞれの場所で全く違うことをやろうと思っているようです。 1つの場所では、プログラムを停止する必要があります。もう一方では、あなたがプログラムを停止したかどうかを確認したい。しかし、あなたはまったく同じ方法でそれを呼び出し、Pythonはあなたの心を読むことができません。だから、それらの呼び出しの1つが間違っている必要があります...それは私が言っていたすべてです。 –

答えて

1

インフィニットループは、実行中のスレッド全体をブロックするため、UIプログラミングではめったに良い解決策ではありません。あなたのメソッドをスケジュールするには、kivyのClockオブジェクトを使用する方が良いでしょう。

from kivy.clock import Clock 

def runStuff(self): 
    Clock.schedule(saySomething, 2) 

Clock.unscheduleを使用してコールバックをスケジュール解除することができます。それはアプリの方法であることをアプリへのアクセス権を持つすべての機能を持っているのは良い練習があるので、

def exit(self): 
    App.get_running_app().stop() 
    Clock.unschedule(saySomething) 

また、get_running_appの使用は一般的に、お勧めしません。あなたはそれぞれの関数にself引数を含んでいたので、とにかくあなたがやろうとしていたものだと思います。

class AudibleCoachApp(App): 

    def runStuff(self): 
     Clock.schedule(saySomething, 2) 

    def exit(self): 
     Clock.unschedule(saySomething) 
     self.stop() 

あなたはself.runStuffself.exitbuildrunStuffexitの通話を変更する必要があります。

btn1.bind(on_press=self.runStuff) # binding the button with the function   

...

btn3.bind(on_press=self.exit) # binding the button with the function below 

そして、あなたは明示的にGC'dであることからClockを停止することをアプリにバインドする必要があります。

if __name__ == '__main__': 
    app = AudibleCoachApp() 
    app.run() 

要するに、コードは(kivy.clockからClockのインポートを追加することを忘れないでください)以下になります。

from kivy.clock import Clock 

# ... 

def saySomething(): 
    ttsSpeak('Say this phrase') 

class AudibleCoachApp(App): 

    def runStuff(self): 
     Clock.schedule(saySomething, 2) 

    def exit(self): 
     Clock.unschedule(saySomething) 
     self.stop() 

    def build(self): 
     layout = BoxLayout(padding=7, spacing=3, orientation='vertical') # set layout of the screen 
     btn1 = Button(text='Start it', size_hint=(1, .66)) # create a button instance 
     btn1.bind(on_press=runStuff) # binding the button with the function below 
     btn3 = Button(text='Exit', size_hint=(1, .17)) # create a button instance 
     btn3.bind(on_press=exit) # binding the button with the function below 
     layout.add_widget(btn1) # physically add the button onto the layout 
     layout.add_widget(btn2) # physically add the button onto the layout 
     layout.add_widget(btn3) # physically add the button onto the layout 

     return layout 

if __name__ == '__main__': 
    app = AudibleCoachApp() 
    app.run() 

上記のコードはすべてテストされていません。エラーが見つかった場合は、コメントを残してください。