我有一堆灯我试图控制。而不是每个按钮状态更改调用一个独特的函数,我想尝试并具有多功能函数,因为这是什么功能(据我所知)。
按钮调用功能:
ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.changeKS1(1)
功能:
def changeKS1(self,change):
if change==1 and b.get_light(1, 'on'):
self.KitchenSpot1(False)
else:
self.KitchenSpot1(True)
该函数然后调用此函数以使用第三方库来物理地改变灯的状态。
def KitchenSpot1(self,state):
lights[0].name
lights[0].on = state
我通过的原因" 1"功能内部是因为它不喜欢没有任何东西传递(我不知道它为什么不喜欢它)。如果你还没有猜到,我就是新手。我有一点cpp微控制器背景,但我试图了解python和基于PC的编程。我正在寻找一些关于如何最好地压缩这一点并使其尽可能高效的建议。我可能对python不太了解,但是,我知道我不应该在30次内输入几乎相同的东西。
提前感谢任何能分享他们智慧的人。
注意到我正在使用kivy和python来生成按钮。
完整的main.py代码:
from kivy.properties import StringProperty
import kivy
from kivy.uix.togglebutton import ToggleButton
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.app import App
kivy.require('1.10.0')
from phue import Bridge
import nest
b = Bridge('xx.xxx.xxx.xxx')
b.connect()
b.get_api()
lights = b.lights
class Controller(GridLayout):
state = StringProperty('down')
def __init__(self, **kwargs):
super(Controller, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1.0 / 60.0)
def KitchenSpot1(self,state):
lights[0].name
lights[0].on = state
def changeKS1(self,change):
if change==1 and b.get_light(1, 'on'):
self.KitchenSpot1(False)
else:
self.KitchenSpot1(True)
def KitchenSpot2(self,state):
lights[1].name
lights[1].on = state
def KitchenSpot3(self,state):
lights[2].name
lights[2].on = state
def OfficeSpot1(self,state):
lights[3].name
lights[3].on = state
def OfficeSpot2(self,state):
lights[4].name
lights[4].on = state
def OfficeSpot3(self,state):
lights[5].name
lights[5].on = state
def OfficeSpot4(self,state):
lights[6].name
lights[6].on = state
def JuliaBedside(self,state):
lights[7].name
lights[7].on = state
def JohnBedside(self,state):
lights[8].name
lights[8].on = state
def update(self, dt):
if b.get_light(1, 'on'):
self.state = 'down'
else:
self.state = 'normal'
class ActionApp(App):
def build(self):
return Controller()
if __name__ == "__main__":
myApp = ActionApp()
myApp.run()
完整的action.kv代码
<Controller>:
cols: 4
rows: 3
spacing: 10
state: "normal"
ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.changeKS1(1)
#on_release: root.KitchenSpot1(False)
#state1 = app.update.h
state: root.state
ToggleButton:
text: "Kitchen Spot 2"
Button:
text: "Kitchen Spot 3"
Button:
text: "Kitchen Spot 4"
Button:
text: "Office Spot 1"
Button:
text: "Office Spot 2"
Button:
text: "Office Spot 3"
Button:
text: "Office Spot 4"
更新: Python程序:
def lightcontrol(self,lightnumber):
if b.get_light(1, 'on'):
lights[lightnumber].name
lights[lightnumber].on (False)
#self.KitchenSpot1(False)
else:
lights[lightnumber].name
lights[lightnumber].on (True)
#self.KitchenSpot1(True)
Kivy按钮:
ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.lightcontrol(0)
答案 0 :(得分:1)
让每个按钮调用相同的功能,但使用不同的参数。
# Add the a number parameter here based on what you've
def KitchenSpot(self,state, light_index):
lights[light_index].name
lights[light_index].on = state
然后在KV文件中
Button:
text: "Kitchen Spot 3"
on_press: root.KitchenSpot(state, light_index = 3)
Button:
text: "Kitchen Spot 4"
on_press: root.KitchenSpot(state, light_index = 4)
您只需要创建一个函数,每个按钮都会传入相关的light_index编号。
答案 1 :(得分:0)
既不知道kivy也不知道我已经尝试通过抽象方法的定义(以及创建action.kv
文件)来减少代码冗余问题。
所以我希望你能找到这个:首先,我将在全局变量中定义按钮的所有相关数据,如:
BUTTONS = [
{'id': 0, 'methodname': 'KitchenSpot1', 'text': 'Kitchen Spot 1'},
{'id': 1, 'methodname': 'KitchenSpot2', 'text': 'Kitchen Spot 2'},
...
]
然后使用所有独特方法定义您的Controller类,就像您所做的那样(__init__
和update
;但是我不知道应该做什么更新,我只是把它留下来定):
class Controller(GridLayout):
state = StringProperty('down')
def __init__(self, **kwargs):
super(Controller, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1.0 / 60.0)
def update(self, dt):
if b.get_light(1, 'on'):
self.state = 'down'
else:
self.state = 'normal'
# this iteratively creates your button-individual methods
for button_dict in BUTTONS:
def func(self, state):
lights[button_dict['id']].name # whatever this might do just adressing the name attribute. Is it a python-property on lights that does some action?
lights[button_dict['id']].on = state
def func_change(self, change):
if change == True and b.get_light(button_dict['id'], 'on'):
getattr(self, button_dict['methodname'])(False)
else:
getattr(self, button_dict['methodname'])(True)
# create .KitchenSpot1, .KitchenSpot2, ...
setattr(Controller, button_dict['methodname'], func)
# create .changeKitchenSpot1, .changeKitchenSpot2, ...
setattr(Controller, "change{}".format(button_dict['methodname']), func_change)
实例化的Controller将根据所有方法名和change-methodnames命名绑定方法。
最后,您可以动态创建action.kv
文件
actionkv_toggle_button = """
ToggleButton:
id: {methodname}Toggle
text: "{text}"
on_press: root.change{methodname}(1)
#on_release: root.{methodname}(False)
#state1 = app.update.h
state: root.state
"""
actionkv_str = """
<Controller>:
cols: 4
rows: 3
spacing: 10
state: "normal"
{buttons}
""".format(
buttons="".join([
actionkv_toggle_button.format(
methodname=button_dict['methodname'],
text=button_dict['text']
) for button_dict in BUTTONS
])
)
这给出了输出
<Controller>:
cols: 4
rows: 3
spacing: 10
state: "normal"
ToggleButton:
id: KitchenSpot1Toggle
text: "Kitchen Spot 1"
on_press: root.changeKitchenSpot1(1)
#on_release: root.KitchenSpot1(False)
#state1 = app.update.h
state: root.state
ToggleButton:
id: KitchenSpot2Toggle
text: "Kitchen Spot 2"
on_press: root.changeKitchenSpot2(1)
#on_release: root.KitchenSpot2(False)
#state1 = app.update.h
state: root.state
将其保存到文件
with open('action.kv', 'w') as f:
f.write(actionkv_str)
有用的链接: