Luc*_*uke 4 events tkinter python-3.x
无法弄清楚如何实现事件系统。我正在用 tkinter 做项目。我需要使用事件。如何拥有像 Java 或 C# 事件这样的事件?
我搜索了很多但找不到正确的方法。
这是我试图实现的事件类。
class Event(object):
def __init__(self):
self.handlers = []
def add(self, handler):
self.handlers.append(handler)
return self
def remove(self, handler):
self.handlers.remove(handler)
return self
def fire(self, sender, earg=None):
for handler in self.handlers:
value = handler()
self.remove(handler)
return value
__iadd__ = add
__isub__ = remove
__call__ = fire
Run Code Online (Sandbox Code Playgroud)
这是汽车类
class Car:
_speed = 0
events = Event()
def speed_up(self):
self._speed += 10
def speed_down(self):
self._speed -= 10
def get_speed(self):
return self._speed
Run Code Online (Sandbox Code Playgroud)
最后是 Window 类(tkinter 窗口)
class Window(tk.Tk):
def __init__(self):
super().__init__()
self.car = Car()
tk.Button(self, text="Speed Up", command=self.increase_speed).grid(sticky="nsew")
tk.Button(self, text="Speed Down", command=self.decrease_speed).grid(sticky="nsew")
self.speed_label = tk.Label(self, text="0")
self.speed_label.grid(sticky="nsew")
self.mainloop()
def increase_speed(self):
self.car
def decrease_speed(self):
pass
Run Code Online (Sandbox Code Playgroud)
我想完成: 1)在“加速”按钮上单击“speed_up”应添加到事件中。2)它应该改变self.speed_label的值。3) 它应该是类似 c# / Java events 或 c# delagetes 的东西。
更新!我正在搜索/编辑并提出了一个解决方案。不知道这个解决方案好不好。我会问我的老师这是否是实施活动的好方法。但目前代码如下所示:
import tkinter as tk
class Observer():
_observers = []
def __init__(self):
self._observers.append(self)
self._observed_events = []
def observe(self, event_name, callback_fn):
self._observed_events.append({'event_name' : event_name, 'callback_fn' : callback_fn})
class Event():
def send(self, event_name, *callback_args):
for observer in Observer._observers:
for observable in observer._observed_events:
if observable['event_name'] == event_name:
observable['callback_fn'](*callback_args)
def receive(self, event_name, *callback_args):
for observer in Observer._observers:
for observable in observer._observed_events:
if observable['event_name'] == event_name:
response = observable['callback_fn'](*callback_args)
return response
class Car(Observer):
def __init__(self):
Observer.__init__(self)
self._current_speed = 0
def speed(self):
self._current_speed += 10
def slow(self):
self._current_speed -= 10
def current(self):
return self._current_speed
class Window(tk.Tk):
def __init__(self):
super().__init__()
self._car = Car()
self.store()
self.events = Event()
tk.Button(self, text="Speed Up", command=lambda:self.change_speed("speed")).grid(sticky="nsew")
tk.Button(self, text="Slow Down", command=lambda:self.change_speed("slow")).grid(sticky="nsew")
self.label = tk.Label(self, text=0)
self.label.grid()
self.settings()
def store(self):
self._car.observe("speed", self._car.speed)
self._car.observe("slow", self._car.slow)
self._car.observe("current", self._car.current)
def settings(self):
self.mainloop()
def change_speed(self, event):
self.events.send(event)
self.label.config(text=self.events.receive("current"))
Window()
Run Code Online (Sandbox Code Playgroud)
在没有完全分析问题中的代码的情况下,我想说您使用函数回调的方向是正确的。据我所知,这是因为 Python 没有事件的本机实现。
一些有用的库或在此基础上构建的示例可以在观察者模式、模仿事件或相关问题的答案等文章中看到。
这是我能想到的最简单的代码,它说明了回调概念,不带参数:
def on_notify():
print("OK, I'm up-to-date")
def do_something(update):
# do whatever I need to do
print("I've changed\n")
update()
do_something(on_notify)
Run Code Online (Sandbox Code Playgroud)
哪个输出:
我已经改变了
好的,我已经更新了
当事件发生时,我们的“worker”函数需要一个函数参数来调用。在本例中,它只有一个,但可以使用一个列表,这样我们就有很多观察者,这就是其他更完整的示例所做的。
同样相关的是事件对象,它是对象在线程之间通信的机制,对于用户界面来说这是值得考虑的。我的猜测是,大多数实现“丢失事件”功能的库和框架都基于这些核心方法中的一个或两个。
归档时间: |
|
查看次数: |
14810 次 |
最近记录: |