为什么在 Kivy 中无法通过回调触发事件
Why it's not possible to trigger an event from callback in Kivy
大家好!
我 运行 遇到 Kivy + 事件和回调 的问题。
当我尝试 运行 来自另一个回调的回调时 - 它失败了。
第一个回调 on_spinner1_select
应该用 ClockEvent self._myevent = Clock.create_trigger(...)
触发第二个回调 _update_something
。第一个回调被正确调用,但 _update_something
永远不会被调用。
这种行为的原因是什么?
这是我的简单示例:
import kivy
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
import time
kv_app_layout = """
#<KvLang>
MyLayout:
id: _mylayout
spinner1: _spnr1
label1: _lbl1
orientation: 'vertical'
padding: 2
spacing: 2
canvas.before:
Color:
rgba: 1, 1, 1, 1
Line:
width: .5
rectangle: (self.x+1, self.y-1, self.width-2, self.height-1)
Spinner:
id: _spnr1
text: 'Some Text'
values: ['A', 'B', 'C', 'D']
size_hint: 1, .5
on_text: root.on_spinner1_select(self.text)
Label:
id: _lbl1
size_hint: 1, .5
#</KvLang>
"""
class MyLayout(BoxLayout):
spinner1 = ObjectProperty(None)
label1 = ObjectProperty(None)
def __init__(self, **kwargs):
self._myevent = Clock.create_trigger(lambda dt: self._update_something)
super().__init__(**kwargs)
def on_spinner1_select(self, text):
self._myevent()
def _update_something(self):
print(f"Called: {time.asctime()}")
self.label1.text = f"{self.spinner1.text} called on {time.asctime()}"
class SampleApp(App):
def build(self):
return Builder.load_string(kv_app_layout)
if __name__ == '__main__':
SampleApp().run()
我在:
- python 3.7 x64
- 基维 2.0.0
通过稍微修改您的代码,我设法调用了 _update_something
Here's the result of the code
import kivy
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
import time
kv_app_layout = """
#<KvLang>
MyLayout:
id: _mylayout
spinner1: _spnr1
label1: _lbl1
orientation: 'vertical'
padding: 2
spacing: 2
canvas.before:
Color:
rgba: 1, 1, 1, 1
Line:
width: .5
rectangle: (self.x+1, self.y-1, self.width-2, self.height-1)
Spinner:
id: _spnr1
text: 'Some Text'
values: ['A', 'B', 'C', 'D']
size_hint: 1, .5
on_text: root.on_spinner1_select(self.text)
Label:
id: _lbl1
size_hint: 1, .5
#</KvLang>
"""
class MyLayout(BoxLayout):
spinner1 = ObjectProperty(None)
label1 = ObjectProperty(None)
def __init__(self, **kwargs):
self._myevent = Clock.create_trigger(self._update_something)
super().__init__(**kwargs)
def on_spinner1_select(self, text):
self._myevent()
def _update_something(self,dt):
print(f"Called: {time.asctime()}")
self.label1.text = f"{self.spinner1.text} called on {time.asctime()}"
class SampleApp(App):
def build(self):
return Builder.load_string(kv_app_layout)
if __name__ == '__main__':
SampleApp().run()
确保遵循 Kivy Documentation
中规定的格式
使用 lambda 函数应该也可以,但我不确定。
大家好!
我 运行 遇到 Kivy + 事件和回调 的问题。
当我尝试 运行 来自另一个回调的回调时 - 它失败了。
第一个回调 on_spinner1_select
应该用 ClockEvent self._myevent = Clock.create_trigger(...)
触发第二个回调 _update_something
。第一个回调被正确调用,但 _update_something
永远不会被调用。
这种行为的原因是什么?
这是我的简单示例:
import kivy
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
import time
kv_app_layout = """
#<KvLang>
MyLayout:
id: _mylayout
spinner1: _spnr1
label1: _lbl1
orientation: 'vertical'
padding: 2
spacing: 2
canvas.before:
Color:
rgba: 1, 1, 1, 1
Line:
width: .5
rectangle: (self.x+1, self.y-1, self.width-2, self.height-1)
Spinner:
id: _spnr1
text: 'Some Text'
values: ['A', 'B', 'C', 'D']
size_hint: 1, .5
on_text: root.on_spinner1_select(self.text)
Label:
id: _lbl1
size_hint: 1, .5
#</KvLang>
"""
class MyLayout(BoxLayout):
spinner1 = ObjectProperty(None)
label1 = ObjectProperty(None)
def __init__(self, **kwargs):
self._myevent = Clock.create_trigger(lambda dt: self._update_something)
super().__init__(**kwargs)
def on_spinner1_select(self, text):
self._myevent()
def _update_something(self):
print(f"Called: {time.asctime()}")
self.label1.text = f"{self.spinner1.text} called on {time.asctime()}"
class SampleApp(App):
def build(self):
return Builder.load_string(kv_app_layout)
if __name__ == '__main__':
SampleApp().run()
我在:
- python 3.7 x64
- 基维 2.0.0
通过稍微修改您的代码,我设法调用了 _update_something
Here's the result of the code
import kivy
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
import time
kv_app_layout = """
#<KvLang>
MyLayout:
id: _mylayout
spinner1: _spnr1
label1: _lbl1
orientation: 'vertical'
padding: 2
spacing: 2
canvas.before:
Color:
rgba: 1, 1, 1, 1
Line:
width: .5
rectangle: (self.x+1, self.y-1, self.width-2, self.height-1)
Spinner:
id: _spnr1
text: 'Some Text'
values: ['A', 'B', 'C', 'D']
size_hint: 1, .5
on_text: root.on_spinner1_select(self.text)
Label:
id: _lbl1
size_hint: 1, .5
#</KvLang>
"""
class MyLayout(BoxLayout):
spinner1 = ObjectProperty(None)
label1 = ObjectProperty(None)
def __init__(self, **kwargs):
self._myevent = Clock.create_trigger(self._update_something)
super().__init__(**kwargs)
def on_spinner1_select(self, text):
self._myevent()
def _update_something(self,dt):
print(f"Called: {time.asctime()}")
self.label1.text = f"{self.spinner1.text} called on {time.asctime()}"
class SampleApp(App):
def build(self):
return Builder.load_string(kv_app_layout)
if __name__ == '__main__':
SampleApp().run()
确保遵循 Kivy Documentation
中规定的格式使用 lambda 函数应该也可以,但我不确定。