使用Kivy在Python中传递事件
我刚开始学习Python和Kivy,想在按下任何按钮时清除一个容器里的所有小部件,我的代码如下:
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.label import Label
spots={}
class spot(Button):
'''
classdocs
'''
def __init__(self, **kwargs):
'''
Constructor
'''
super(spot,self).__init__(**kwargs)
self.ismine=False
if 'text' in kwargs:
self.text=kwargs['text']
else:
self.text="X"
def on_press(self, *args, **kwargs):
#return Button.on_press(self, *args, **kwargs)
game.spottouched(self, self.text)
class game(BoxLayout):
def __init__(self,**kwargs):
super(game,self).__init__(**kwargs)
self.m=minesholder(rows=25, cols=25)
self.add_widget(self.m)
self.attachtogrid()
def attachtogrid(self):
self.m.clear_widgets()
spots.clear()
for r in range(0,25):
for c in range(0,25):
idd=str(r)+","+str(c)
spots[idd]=idd
self.m.add_widget(spot(text=idd))
def spottouched(self,spotid):
#popup=Popup(title=spotid)
#popup.open()
self.clear_widgets()
最后一行是用来清除小部件的,spot类有一个on_press事件。我想把按钮的on_press事件传递给一个包含的boxlayout(游戏类),你能告诉我或者指引我一下,怎么把这些事件传递过去吗?
谢谢你。
2 个回答
1
game.spottouched(self, self.text)
你可能对Python的类有些误解。你需要清除的是你实际使用的那个游戏实例中的小部件,也就是你通过写game()
创建的那个实例。你需要用这个实例的引用,调用instance.spottouched(spotid)
来执行那个实例的方法。
而你现在做的是通过类的定义来调用这个方法,这样做其实没有意义,你也不应该这样做。实际上,你基本上永远不应该这样做。
无论如何,修复这个问题的方法取决于你是如何构建你的应用的,但归根结底,你需要在某个地方保留对游戏实例的引用,这样点位实例才能看到它。最佳的方法取决于你代码的其他部分,但你总是可以通过应用类来实现,比如:
App.get_running_app().game = game()
然后在后面
App.get_running_app().game.spottouched(self.text)
这只是一个例子,有时候这样做可能并不好。
另外,记得用大写字母开头命名你的部件!kv语言用这个来识别它们,如果你不这样命名,会遇到问题。这也是Python中的一个重要约定,值得遵循。
1
我觉得根据你对@inclement回答的评论,这正是你想要的:把按钮上的on_press
方法去掉。你应该绑定到事件上,这样做会更像WPF。
for r in range(0,25):
for c in range(0,25):
idd=str(r)+","+str(c)
spots[idd]=idd
s = spot(text=idd)
self.m.add_widget(s)
s.bind(on_press=self.spottouched)
所以self.spottouched
就像是处理spot
的on_press
事件的一个事件处理器。
s.bind(on_press=self.spottouched)
大概是这样的:
AddHandler s.Click, AddressOf spottouched
注意,以这种方式添加处理器时,处理器会接收到一个参数,就是spot
的实例。你可以从这个实例中获取spot.text
。