2016-12-10 7 views
2

関連質問hereスレーブモードでKivy EventLoopを実行するには?

私はどこか別の場所からそれを更新するために実行し、力からKivyのイベントループを防止runTouchApp機能のためslaveプロパティを発見しました。ここで
は、そのプロパティが使用されているapp.pyの一部です:アプリはスレーブ・モードで実行されていない場合

ここ
# we are in a slave mode, don't do dispatching. 
if slave: 
    return 

try: 
    if EventLoop.window is None: 
     _run_mainloop() 
    else: 
     EventLoop.window.mainloop() 
finally: 
    stopTouchApp() 

、我々はメインループを実行する方法の2つの選択肢があります。
最初のものは、_run_mainloop()関数はかなり単純です。EventLoop.run()を呼び出すだけで、無限にEventLoop.idle()が呼び出されます。
これは、GUIを実行し続けるためには、idleに電話する必要があると信じることができます。

しかし、kivy.core.window.WindowSDLのメソッドmainloopを呼び出す2番目のオプションがあります。
このメソッドは、別のメソッドである_mainloopを呼び出すことで機能し、これは興味深いところです。このメソッドの定義はhugeであり、あらゆる種類のイベントを処理します。

def start_event(self): 
    while True: 
     EventLoop.idle() 

は推測何、アプリはdoesnの:私は(期待して)start_event方法でこれを置けば、今

class TestApp(App): 
    def start_event(self): 
     pass 

    def build(self): 
     return Button(text = "hello") 

    def run(self): 
     # This definition is copied from the superclass 
     # except for the start_event call and slave set to True 

     if not self.built: 
      self.load_config() 
      self.load_kv(filename=self.kv_file) 
      root = self.build() 
      if root: 
       self.root = root 

     if self.root: 
      Window.add_widget(self.root) 

     window = EventLoop.window 
     if window: 
      self._app_window = window 
      window.set_title(self.get_application_name()) 
      icon = self.get_application_icon() 
      if icon: 
       window.set_icon(icon) 
      self._install_settings_keys(window) 


     self.dispatch('on_start') 
     runTouchApp(slave = True) 
     self.start_event() # Here we start updating 
     self.stop() 

だから、大丈夫、私は、スレーブモードでの私のアプリを実行しましたタッチイベントやフリーズに反応しません。

def start_event(self): 
    EventLoop.window.mainloop() 

そして突然、すべてが正常に再び作業を開始しました:
だから私の代わりに、ウィンドウのメインループ呼び出そうとしました。しかし、ここでの問題は、無限ループなので、このような呼び出しは永遠にブロックされるため、EventLoop.idle

などのワンタイムアップデートコールはありません。このようなワンタイムコールを使用してアプリケーションを実行し続けるにはどうすればいいですか?

答えて

1

まあ、これはPythonはそう、それは無限ではありませんので、あなたは常に猿このmainloop機能にパッチを適用することができ、あなたがWindowSDLプロバイダに固執したいと仮定している:

from kivy.app import App 
from kivy.uix.boxlayout import BoxLayout 
from kivy.lang import Builder 
from kivy.base import EventLoop 

Builder.load_string(''' 
<MyWidget>: 
    Button: 
     text: 'test' 
     on_press: print('doing my job') 
''') 

# https://github.com/kivy/kivy/blob/master/kivy/core/window/window_sdl2.py#L630 
def mainloop(self): 
    # replaced while with if 
    if not EventLoop.quit and EventLoop.status == 'started': 
     try: 
      self._mainloop() 
     except EventLoop.BaseException as inst: 
      # use exception manager first 
      r = EventLoop.ExceptionManager.handle_exception(inst) 
      if r == EventLoop.ExceptionManager.RAISE: 
       EventLoop.stopTouchApp() 
       raise 
      else: 
       pass 


class MyWidget(BoxLayout): 
    pass 


if __name__ == '__main__': 
    from kivy.base import runTouchApp 
    runTouchApp(MyWidget(), slave=True) 
    # monkey patch 
    EventLoop.window.mainloop = mainloop 
    while True: 
     EventLoop.window.mainloop(EventLoop.window) 
     print('do the other stuff') 
     if EventLoop.quit: 
      break 

それはしかし本当にハックですので、I」プロダクションコードでそのようなものを実行することはお勧めしません。

関連する問題