2016-12-10 1 views
2

내가 다른 곳에서 업데이트하는 실행과 힘에서 Kivy의 이벤트 루프를 방지 runTouchApp 함수에 대한 slave 속성을 발견했습니다 here슬레이브 모드에서 Kivy EventLoop을 실행하는 방법은 무엇입니까?

관련 질문입니다.
여기에 해당 속성이 사용되는 경우 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() 

앱에서 슬레이브 모드에서 실행되고 있지 않은 경우, 우리는 주회 돌이를 실행하는 방법에 대한 두 가지 선택이있다.
첫 번째 것은 _run_mainloop() 함수는 꽤 똑바로 작동합니다 - EventLoop.run()을 호출하고 차례로 무한히 EventLoop.idle()을 호출합니다.
그러면 GUI를 계속 실행하려면 idle으로 전화하면됩니다.

하지만 두 번째 옵션은 kivy.core.window.WindowSDLmainloop입니다.
이 메서드는 다른 메서드 인 _mainloop을 호출하여 작동하며 여기서는 흥미로운 부분입니다. 이 메소드의 정의는 huge이며 모든 종류의 이벤트를 처리합니다.

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

추측 어떤 앱이 아무튼 : 나는 (기대치)를 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

음, 이것은 그래서 당신은 WindowSDL 제공에 충실하려는 가정 파이썬, 당신은 항상 원숭이이 mainloop 기능을 패치 할 수 있습니다 :

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 

그것은 정말로 해키 때문에 내가 ' 프로덕션 코드에서 이와 유사한 것을 실행하지 않는 것이 좋습니다.

관련 문제