gpt4 book ai didi

python - 随机时间绑定(bind)工作

转载 作者:太空宇宙 更新时间:2023-11-03 19:07:58 25 4
gpt4 key购买 nike

我正在为 kivy 编写一个自定义小部件(请参阅 this 问题),但我刚刚发现,由于某种未知的原因,有时 bind 方法实际上并未绑定(bind)回调。

在我的类里面,我有以下代码:

def __init__(self, **kwargs):
super(SpinBox, self).__init__(**kwargs)

self._value_label = Label(text=str(self.value))
self.inc_button = TimedButton(text='+')
self.dec_button = TimedButton(text='-')


def inc(inst):
if float(self.value) + float(self.step) <= self.max_value:
self.value += self.step

def dec(inst):
if float(self.value) - float(self.step) >= self.min_value:
self.value -= self.step

self.inc_button.bind(on_press=inc)
self.inc_button.bind(on_time_slice=inc)
self.dec_button.bind(on_press=dec)
self.dec_button.bind(on_time_slice=dec)
# ...

其中TimedButton是另一个自定义类。它是一个 Button 子类,在 on_touch_down 上启动计时器,如果在一段时间后没有收到 on_touch_up ,它会认为长按并开始每隔几毫秒使用 Clock.schedule_interval 调度 on_time_slice 事件。

因此,尝试像这样使用我的自定义类:

class MyApp(App):
def build(self):
return SpinBox()

MyApp().run()

根本没有增加。

如果我这样做:

class MyApp(App):
def build(self):
s = SpinBox()
def inc(inst):
s.value += 1
s.inc_button.bind(on_time_slice=inc)
return s
MyApp().run()

该值在每次on_time_slice 事件时递增。我不明白为什么 MyApp 类中的绑定(bind)有效,而 SpinBox.__init__ 方法中的绑定(bind)无效。我做错了什么?

最佳答案

我找到了解决办法。我没有绑定(bind) on_touch_downon_touch_up,而是尝试绑定(bind) state 属性,在 中实现 on_state 方法>TimedButton 并且它可以工作。我仍然不明白为什么以前的实现在单独使用时有效,但在 SpinBox 中不起作用,除非直接在 App 类中绑定(bind)函数。

无论如何,由于看起来 TimedButton 类与它有关,所以这是旧实现的代码:

class TimedButton(Button):
"""A simple ``Button`` subclass that produces an event at regular intervals
when pressed.

This class, when long-pressed, emits an ``on_time_slice`` event every
``time_slice`` milliseconds.

:param long_press_interval: Defines the minimum time required to consider
the press a long-press.
:type long_press_interval: int
:param time_slice: The number of milliseconds of each slice.
:type time_slice: int
"""

def __init__(self, long_press_interval=550, time_slice=225, **kwargs):
super(TimedButton, self).__init__(**kwargs)

self.long_press_interval = long_press_interval
self.time_slice = time_slice

self._touch_start = None
self._touch_uid = None
self._long_press_callback = None
self._slice_callback = None

self.register_event_type('on_time_slice')
self.register_event_type('on_long_press')


def on_touch_down(self, touch):
start_time = time.time()
self._touch_start = start_time
self._touch_uid = touch.uid

def callback(dt):
self._check_long_press(dt)

Clock.schedule_once(callback, self.long_press_interval / 1000.0)
self._long_press_callback = callback
super(TimedButton, self).on_touch_down(touch)

def _check_long_press(self, dt):
delta = dt * 1000
if delta > self.long_press_interval and self._touch_uid is not None:
self.dispatch('on_long_press')
self._long_press_callback = None
def slice_callback(dt):
self.dispatch('on_time_slice')

Clock.schedule_interval(slice_callback, self.time_slice / 1000.0)

self._slice_callback = slice_callback

def on_touch_up(self, touch):
end_time = time.time()
delta = (end_time - (self._touch_start or 0)) * 1000
Clock.unschedule(self._slice_callback)
if (self._long_press_callback is not None and
delta > self.long_press_interval):
self.dispatch('on_long_press')
self._touch_start = self._touch_uid = None
self._long_press_callback = self._slice_callback = None
super(TimedButton, self).on_touch_up(touch)


def on_long_press(self):
pass

def on_time_slice(self):
pass

这是使用 state 的新代码,效果非常好:

class TimedButton(Button):
"""A simple ``Button`` subclass that produces an event at regular intervals
when pressed.

This class, when long-pressed, emits an ``on_time_slice`` event every
``time_slice`` milliseconds.

:param long_press_interval: Defines the minimum time required to consider
the press a long-press.
:type long_press_interval: int
:param time_slice: The number of milliseconds of each slice.
:type time_slice: int
"""

def __init__(self, long_press_interval=550, time_slice=225, **kwargs):
super(TimedButton, self).__init__(**kwargs)

self.long_press_interval = long_press_interval
self.time_slice = time_slice

self._touch_start = None
self._long_press_callback = None
self._slice_callback = None

self.register_event_type('on_time_slice')
self.register_event_type('on_long_press')


def on_state(self, instance, value):
if value == 'down':
start_time = time.time()
self._touch_start = start_time

def callback(dt):
self._check_long_press(dt)

Clock.schedule_once(callback, self.long_press_interval / 1000.0)
self._long_press_callback = callback
else:
end_time = time.time()
delta = (end_time - (self._touch_start or 0)) * 1000
Clock.unschedule(self._slice_callback)
if (self._long_press_callback is not None and
delta > self.long_press_interval):
self.dispatch('on_long_press')
self._touch_start = None
self._long_press_callback = self._slice_callback = None

def _check_long_press(self, dt):
delta = dt * 1000
if delta > self.long_press_interval and self.state == 'down':
self.dispatch('on_long_press')
self._long_press_callback = None

def slice_callback(dt):
self.dispatch('on_time_slice')
return self.state == 'down'

Clock.schedule_interval(slice_callback, self.time_slice / 1000.0)

self._slice_callback = slice_callback


def on_long_press(self):
pass

def on_time_slice(self):
pass

关于python - 随机时间绑定(bind)工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14074979/

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