gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 05:18:38 25 4
gpt4 key购买 nike

相关问题here

我发现了 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()

在这里,如果应用程序不是在从属模式下运行,我们有两种选择来运行主循环。
第一个,_run_mainloop() 函数工作起来非常简单 - 它只是调用 EventLoop.run(),后者又会无限调用 EventLoop.idle( ).
这可能会让我们相信,要保持 GUI 运行,我们只需要调用 idle

但是还有第二个选项,它调用kivy.core.window.WindowSDL的方法mainloop
该方法通过调用另一个方法 _mainloop 来工作,这就是它变得有趣的地方。所述方法的定义是huge它处理各种事件。

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

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_event 方法(按预期):

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

你猜怎么着,应用程序不响应触摸事件并卡住。
所以我尝试改为调用 Window 的主循环:

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

虽然它真的很 hacky,因此我不建议在生产代码中运行类似的东西。

关于python - 如何在从属模式下运行 Kivy EventLoop?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41077272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com