Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在从属模式下运行Kivy EventLoop?_Python_Python 3.x_Kivy_Event Loop - Fatal编程技术网

Python 如何在从属模式下运行Kivy EventLoop?

Python 如何在从属模式下运行Kivy EventLoop?,python,python-3.x,kivy,event-loop,Python,Python 3.x,Kivy,Event Loop,相关问题 我发现了runTouchApp函数的slave属性,它阻止Kivy的事件循环运行,并强制从其他地方更新它。 下面是使用该属性的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.mai

相关问题

我发现了
runTouchApp
函数的
slave
属性,它阻止Kivy的事件循环运行,并强制从其他地方更新它。
下面是使用该属性的
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()
在这里,如果应用程序没有在从属模式下运行,我们有两个选择如何运行主循环。
第一个函数是
\u run\u mainloop()
函数,它的工作非常简单-它只调用
EventLoop.run()
,而EventLoop.idle()又无限次地调用
EventLoop.idle()

这可能会让我们相信,要保持GUI运行,我们只需要调用
idle

但是还有第二个选项,它调用
kivy.core.window.WindowSDL
的方法
mainloop

该方法通过调用另一个方法来工作,即
\u mainloop
,这就是它有趣的地方。该方法的定义是,它处理各种事件

好吧,我在从属模式下运行了我的应用程序:

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()
现在,如果我把它放在
start\u事件
方法中(按预期):

你猜怎么着,该应用程序对触摸事件没有响应并冻结。
因此,我尝试调用窗口的主循环:

def start_event(self):
    EventLoop.window.mainloop()
突然,一切又恢复了正常。但这里的问题是,这样的调用会永远阻塞,因为它是一个无限循环,所以没有像
EventLoop.idle


如何使用这种一次性调用保持应用程序运行?

好吧,这是Python,因此假设您想坚持使用
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
从kivy.app导入应用
从kivy.uix.boxlayout导入boxlayout
从kivy.lang导入生成器
从kivy.base导入EventLoop
Builder.load_字符串(“”)
:
按钮:
文本:“测试”
按:打印(“做我的工作”)
''')
# https://github.com/kivy/kivy/blob/master/kivy/core/window/window_sdl2.py#L630
def主回路(自):
#替换为if
如果不是EventLoop.quit和EventLoop.status==“已启动”:
尝试:
self._mainloop()
除EventLoop.BaseException外,按指令:
#首先使用异常管理器
r=EventLoop.ExceptionManager.handle\u异常(inst)
如果r==EventLoop.ExceptionManager.RAISE:
EventLoop.stopTouchApp()
提升
其他:
通过
类MyWidget(BoxLayout):
通过
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
从kivy.base导入runTouchApp
runTouchApp(MyWidget(),slave=True)
#猴斑
EventLoop.window.mainloop=mainloop
尽管如此:
EventLoop.window.mainloop(EventLoop.window)
打印('做其他事情')
如果EventLoop.quit:
打破
但是它确实很有黑客性,因此我不建议在生产代码中运行类似的东西

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