从 kivy 下拉列表中删除所有按钮
Remove all the button from a kivy dropdown
我是 Python 的新手,我试图解决这个问题,但我不太可能无法做到这一点。
下拉列表是通过 mqtt 动态填充的(例如,这里是蚊子),在选择一个值后,我需要更改屏幕,当我 return 在带有下拉列表的屏幕中时,它应该是空的。
有人有想法吗?
提前谢谢你。
main.py
#-*-coding:utf8;-*-
#qpy:2
#qpy:kivy
#!/usr/bin/python
#@@@@@@ -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.core.window import Window
#from kivy.properties import DictProperty
import xmlrpclib
import calendar
import datetime
from urllib3.util.timeout import current_time
from datetime import date, time, timedelta
import locale
from kivy.uix.togglebutton import ToggleButton
from kivy.properties import ListProperty
from threading import Thread
import paho.mqtt.client as mqtt
import time
from time import sleep
from ConfigParser import SafeConfigParser
class CustomDropDownChip(DropDown):
def __init__(self, **kwargs):
super(CustomDropDownChip, self).__init__(**kwargs)
notes = chip_list
for note in notes:
btn = Button(text='%s' % note, size_hint_y=None, height=int(Window.height)/10)
btn.bind(on_release=lambda btn: self.select('CHIP: ' + btn.text))
self.add_widget(btn)
class StartScreen(Screen):
pass
class InsertBox(Screen):
global chip_list
chip_list = []
global chip_list_empty
chip_list_empty = []
global connected_flag
consommables = ListProperty([])
def buttons_down(self):
app = App.get_running_app()
app.chip_value = self.ids.id_chip.text
app.InsertSelection = 'InsertBoxConfirm'
def on_connect(self, mqttc, obj, flags, rc):
if rc==0:
mqttc.connected_flag=True
connected_flag = True
print("connected OK")
else:
print("Bad connection Returned code=",rc)
def on_disconnect(self, mqttc, obj, rc):
pass
def on_message(self, mqttc, obj, msg):
response = str(msg.payload)
if response not in chip_list:
sleep(1)
chip_list.append(response)
if mqttc.connected_flag == False:
mqttc.on_disconnect()
def on_publish(self, mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(self, mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(self, mqttc, obj, level, string):
print(string)
def __init__(self, **kwargs):
super(InsertBox, self).__init__(**kwargs)
def stop_mqtt(self):
mqttc.disconnect()
def start_mqtt(self):
self.read_chip()
def read_chip(self, *args):
global t
t = Thread(target=self.read_).start()
def read_(self):
mqtt.Client.connected_flag=False#create flag in class
connected_flag = False
global mqttc
mqttc = mqtt.Client(transport="websockets")
mqttc.on_message = self.on_message
mqttc.on_connect = self.on_connect
mqttc.on_publish = self.on_publish
mqttc.on_subscribe = self.on_subscribe
mqttc.on_log = self.on_log
mqttc.connect("test.mosquitto.org", 8080, 60)
mqttc.subscribe("temp/random", 0)
mqttc.loop_forever()
def consume(self, *args):
while self.consommables and time() < (Clock.get_time() + MAX_TIME):
item = self.consommables.pop(0) # i want the first one
label = Factory.MyLabel(text=item)
self.root.ids.id_chip.text = label #add_widget(label)
# @classmethod
def reset_chip_list(self):
chip_list = chip_list_empty
class InsertBoxConfirm(Screen):
def buttons_set(self):
InsertBox.buttons_set()
def buttons_reset(self):
InsertBox.buttons_reset()
class MyScreenManager(ScreenManager):
def SetChip(self, value):
pass
class testdropdownApp(App):
title = "Kivy Drop-Down List Demo"
chip_list = chip_list_empty
chip_value = ''
def build(self):
return MyScreenManager()
if __name__ == '__main__':
testdropdownApp().run()
testdropdown.kv
#:kivy 1.10.0
#:import Factory kivy.factory.Factory
<CustomDropDownChip>:
on_select:
app.root.ids.InsertBox.ids.id_chip.text = '{}'.format(args[1])
app.root.SetChip(args[1])
<StartScreen>:
name: 'StartScreen'
Button:
text: 'Start'
on_release:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<InsertBox>:
name: 'InsertBox'
id: test00
on_enter:
root.reset_chip_list()
root.start_mqtt()
on_leave:
root.stop_mqtt()
GridLayout:
rows: 2
id: test01
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Button:
id: id_chip
text: 'Select chip'
# size_hint_y: .5
spacing: 5
on_release: Factory.CustomDropDownChip().open(self)
GridLayout:
size_hint_y: .2
height: .15
cols: 2
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
# height: .15
Button:
text: "Back"
on_press:
root.reset_chip_list()
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'StartScreen'
Button:
text: 'OK'
on_press:
root.buttons_down()
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBoxConfirm'
<InsertBoxConfirm>:
name: 'InsertBoxConfirm'
on_pre_enter:
id_chip_label.text = app.chip_value
GridLayout:
rows: 2
id: id_InsertBoxConfirm
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Label:
id: id_chip_label
text: 'valore CHIP'
GridLayout:
size_hint_y: .2
height: .15
cols: 1
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
Button:
text: 'OK'
id: button_ok
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<MyScreenManager>:
StartScreen:
id: 'StartScreen'
name: 'StartScreen'
InsertBox:
id: InsertBox
name: 'InsertBox'
InsertBoxConfirm:
id: InsertBoxConfirm
name: 'InsertBoxConfirm'
给你:
for child in self.mydropdownsomething.children[:]:
self.mydropdownsomething.remove_widget(child)
其中 mydropdownsomething 是您动态添加下拉按钮的对象。
有关详细信息,请参阅概述、片段和示例。
概述
kv 文件
- 删除导入语句,
#:import Factory kivy.factory.Factory
- 将
root.reset_chip_list()
从 on_enter:
移动到 on_leave:
- 用新的回调方法替换
Factory.CustomDropDownChip().open(self)
,root.create_open_customdropdown(self)
- 从
on_press:
后退按钮中删除 root.reset_chip_list()
因为当我们离开屏幕时,它会自动触发 on_leave:
事件。
- 将
app.chip_value
替换为 root.manager.chip_value
因为我们会将变量 chip_value
从 App class 移动到根 class.
片段 - kv 文件
Button:
id: id_chip
text: 'Select chip'
spacing: 5
on_release:
root.create_open_customdropdown(self)
Python代码
- 添加导入语句,
from kivy.properties import BooleanProperty, ObjectProperty
- 从
class InsertBox(Screen):
中删除变量(全局chip_list;全局chip_list_empty;全局connected_flag)
- 将
chip_list = []
替换为chip_list = ListProperty([])
; chip_list_empty = []
与 chip_list_empty = ListProperty([])
;并添加 connected_flag = BooleanProperty(False)
- 在
class InsertBox(Screen):
的 class 级别添加 ObjectProperty,dropdown = ObjectProperty(None)
以便我们可以使用它连接到 CustomDropDownChip 对象并将其删除。
- 实现一个新方法,create_open_customdropdown(self, instance): inside
class InsertBox(Screen):
- 在方法中,将
chip_list
替换为self.chip_list
; chip_list_empty
与 self.chip_list_empty
; connected_flag
和 self.connected_flag
- 从
class testdropdownApp():
中删除 chip_list = chip_list_empty
- 将
chip_value = ''
从 class testdropdownApp()
移动到 class MyScreenManager():
- 在
SetChip()
方法中,将pass
替换为self.chip_value = value
- 在CustomDropDownChip的构造函数中,添加
chip_list
作为参数;删除 notes = chip_list
;并将 notes
替换为 chip_list
代码段 - Python 代码
class CustomDropDownChip(DropDown):
def __init__(self, chip_list, **kwargs):
super(CustomDropDownChip, self).__init__(**kwargs)
for note in chip_list:
btn = Button(text='%s' % note, size_hint_y=None, height=int(Window.height)/10)
btn.bind(on_release=lambda btn: self.select('CHIP: ' + btn.text))
self.add_widget(btn)
...
class InsertBox(Screen):
consommables = ListProperty([])
chip_list = ListProperty([])
chip_list_empty = ListProperty([])
connected_flag = BooleanProperty(False)
dropdown = ObjectProperty(None)
def create_open_customdropdown(self, instance):
self.dropdown = CustomDropDownChip(self.chip_list)
self.dropdown.open(instance)
...
def reset_chip_list(self):
print("\tlen(chip_list)=", len(self.chip_list))
self.chip_list = self.chip_list_empty
print("\tlen(chip_list)=", len(self.chip_list))
if self.dropdown is not None:
self.remove_widget(self.dropdown)
例子
main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.core.window import Window
from datetime import time
from threading import Thread
import paho.mqtt.client as mqtt
import time
from time import sleep
from kivy.factory import Factory
from kivy.clock import Clock
from kivy.properties import BooleanProperty, ListProperty, ObjectProperty
MAX_TIME = 1/60.
class CustomDropDownChip(DropDown):
def __init__(self, chip_list, **kwargs):
super(CustomDropDownChip, self).__init__(**kwargs)
for note in chip_list:
btn = Button(text='%s' % note, size_hint_y=None, height=int(Window.height)/10)
btn.bind(on_release=lambda btn: self.select('CHIP: ' + btn.text))
self.add_widget(btn)
class StartScreen(Screen):
pass
class InsertBox(Screen):
consommables = ListProperty([])
chip_list = ListProperty([])
chip_list_empty = ListProperty([])
connected_flag = BooleanProperty(False)
dropdown = ObjectProperty(None)
def create_open_customdropdown(self, instance):
self.dropdown = CustomDropDownChip(self.chip_list)
self.dropdown.open(instance)
def buttons_down(self):
app = App.get_running_app()
app.InsertSelection = 'InsertBoxConfirm'
def on_connect(self, mqttc, obj, flags, rc):
if rc==0:
mqttc.connected_flag = True
self.connected_flag = True
print("connected OK")
else:
print("Bad connection Returned code=",rc)
def on_disconnect(self, mqttc, obj, rc):
pass
def on_message(self, mqttc, obj, msg):
response = str(msg.payload)
if response not in self.chip_list:
sleep(1)
self.chip_list.append(response)
if mqttc.connected_flag == False:
mqttc.on_disconnect()
def on_publish(self, mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(self, mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(self, mqttc, obj, level, string):
print(string)
def __init__(self, **kwargs):
super(InsertBox, self).__init__(**kwargs)
def stop_mqtt(self):
mqttc.disconnect()
def start_mqtt(self):
self.read_chip()
def read_chip(self, *args):
global t
t = Thread(target=self.read_).start()
def read_(self):
mqtt.Client.connected_flag = False # create flag in class
self.connected_flag = False
global mqttc
mqttc = mqtt.Client(transport="websockets")
mqttc.on_message = self.on_message
mqttc.on_connect = self.on_connect
mqttc.on_publish = self.on_publish
mqttc.on_subscribe = self.on_subscribe
mqttc.on_log = self.on_log
mqttc.connect("test.mosquitto.org", 8080, 60)
mqttc.subscribe("temp/random", 0)
mqttc.loop_forever()
def consume(self, *args):
while self.consommables and time() < (Clock.get_time() + MAX_TIME):
item = self.consommables.pop(0) # i want the first one
label = Factory.MyLabel(text=item)
self.root.ids.id_chip.text = label #add_widget(label)
# @classmethod
def reset_chip_list(self):
print("\tlen(chip_list)=", len(self.chip_list))
self.chip_list = self.chip_list_empty
print("\tlen(chip_list)=", len(self.chip_list))
if self.dropdown is not None:
self.remove_widget(self.dropdown)
class InsertBoxConfirm(Screen):
def buttons_set(self):
InsertBox.buttons_set()
def buttons_reset(self):
InsertBox.buttons_reset()
class MyScreenManager(ScreenManager):
chip_value = ''
def SetChip(self, value):
self.chip_value = value
class testdropdownApp(App):
title = "Kivy Drop-Down List Demo"
def build(self):
return MyScreenManager()
def on_stop(self):
self.root.ids.InsertBox.stop_mqtt()
if __name__ == '__main__':
testdropdownApp().run()
testdropdown.kv
#:kivy 1.11.0
<CustomDropDownChip>:
on_select:
app.root.ids.InsertBox.ids.id_chip.text = '{}'.format(args[1])
app.root.SetChip(args[1])
<StartScreen>:
name: 'StartScreen'
Button:
text: 'Start'
on_release:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<InsertBox>:
name: 'InsertBox'
id: test00
on_enter:
root.start_mqtt()
on_leave:
root.stop_mqtt()
root.reset_chip_list()
GridLayout:
rows: 2
id: test01
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Button:
id: id_chip
text: 'Select chip'
# size_hint_y: .5
spacing: 5
on_release:
root.create_open_customdropdown(self)
GridLayout:
size_hint_y: .2
height: .15
cols: 2
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
# height: .15
Button:
text: "Back"
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'StartScreen'
Button:
text: 'OK'
on_press:
root.buttons_down()
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBoxConfirm'
<InsertBoxConfirm>:
name: 'InsertBoxConfirm'
on_pre_enter:
id_chip_label.text = root.manager.chip_value
GridLayout:
rows: 2
id: id_InsertBoxConfirm
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Label:
id: id_chip_label
text: 'valore CHIP'
GridLayout:
size_hint_y: .2
height: .15
cols: 1
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
Button:
text: 'OK'
id: button_ok
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<MyScreenManager>:
StartScreen:
id: 'StartScreen'
name: 'StartScreen'
InsertBox:
id: InsertBox
name: 'InsertBox'
InsertBoxConfirm:
id: InsertBoxConfirm
name: 'InsertBoxConfirm'
输出
我是 Python 的新手,我试图解决这个问题,但我不太可能无法做到这一点。 下拉列表是通过 mqtt 动态填充的(例如,这里是蚊子),在选择一个值后,我需要更改屏幕,当我 return 在带有下拉列表的屏幕中时,它应该是空的。
有人有想法吗? 提前谢谢你。
main.py
#-*-coding:utf8;-*-
#qpy:2
#qpy:kivy
#!/usr/bin/python
#@@@@@@ -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.core.window import Window
#from kivy.properties import DictProperty
import xmlrpclib
import calendar
import datetime
from urllib3.util.timeout import current_time
from datetime import date, time, timedelta
import locale
from kivy.uix.togglebutton import ToggleButton
from kivy.properties import ListProperty
from threading import Thread
import paho.mqtt.client as mqtt
import time
from time import sleep
from ConfigParser import SafeConfigParser
class CustomDropDownChip(DropDown):
def __init__(self, **kwargs):
super(CustomDropDownChip, self).__init__(**kwargs)
notes = chip_list
for note in notes:
btn = Button(text='%s' % note, size_hint_y=None, height=int(Window.height)/10)
btn.bind(on_release=lambda btn: self.select('CHIP: ' + btn.text))
self.add_widget(btn)
class StartScreen(Screen):
pass
class InsertBox(Screen):
global chip_list
chip_list = []
global chip_list_empty
chip_list_empty = []
global connected_flag
consommables = ListProperty([])
def buttons_down(self):
app = App.get_running_app()
app.chip_value = self.ids.id_chip.text
app.InsertSelection = 'InsertBoxConfirm'
def on_connect(self, mqttc, obj, flags, rc):
if rc==0:
mqttc.connected_flag=True
connected_flag = True
print("connected OK")
else:
print("Bad connection Returned code=",rc)
def on_disconnect(self, mqttc, obj, rc):
pass
def on_message(self, mqttc, obj, msg):
response = str(msg.payload)
if response not in chip_list:
sleep(1)
chip_list.append(response)
if mqttc.connected_flag == False:
mqttc.on_disconnect()
def on_publish(self, mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(self, mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(self, mqttc, obj, level, string):
print(string)
def __init__(self, **kwargs):
super(InsertBox, self).__init__(**kwargs)
def stop_mqtt(self):
mqttc.disconnect()
def start_mqtt(self):
self.read_chip()
def read_chip(self, *args):
global t
t = Thread(target=self.read_).start()
def read_(self):
mqtt.Client.connected_flag=False#create flag in class
connected_flag = False
global mqttc
mqttc = mqtt.Client(transport="websockets")
mqttc.on_message = self.on_message
mqttc.on_connect = self.on_connect
mqttc.on_publish = self.on_publish
mqttc.on_subscribe = self.on_subscribe
mqttc.on_log = self.on_log
mqttc.connect("test.mosquitto.org", 8080, 60)
mqttc.subscribe("temp/random", 0)
mqttc.loop_forever()
def consume(self, *args):
while self.consommables and time() < (Clock.get_time() + MAX_TIME):
item = self.consommables.pop(0) # i want the first one
label = Factory.MyLabel(text=item)
self.root.ids.id_chip.text = label #add_widget(label)
# @classmethod
def reset_chip_list(self):
chip_list = chip_list_empty
class InsertBoxConfirm(Screen):
def buttons_set(self):
InsertBox.buttons_set()
def buttons_reset(self):
InsertBox.buttons_reset()
class MyScreenManager(ScreenManager):
def SetChip(self, value):
pass
class testdropdownApp(App):
title = "Kivy Drop-Down List Demo"
chip_list = chip_list_empty
chip_value = ''
def build(self):
return MyScreenManager()
if __name__ == '__main__':
testdropdownApp().run()
testdropdown.kv
#:kivy 1.10.0
#:import Factory kivy.factory.Factory
<CustomDropDownChip>:
on_select:
app.root.ids.InsertBox.ids.id_chip.text = '{}'.format(args[1])
app.root.SetChip(args[1])
<StartScreen>:
name: 'StartScreen'
Button:
text: 'Start'
on_release:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<InsertBox>:
name: 'InsertBox'
id: test00
on_enter:
root.reset_chip_list()
root.start_mqtt()
on_leave:
root.stop_mqtt()
GridLayout:
rows: 2
id: test01
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Button:
id: id_chip
text: 'Select chip'
# size_hint_y: .5
spacing: 5
on_release: Factory.CustomDropDownChip().open(self)
GridLayout:
size_hint_y: .2
height: .15
cols: 2
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
# height: .15
Button:
text: "Back"
on_press:
root.reset_chip_list()
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'StartScreen'
Button:
text: 'OK'
on_press:
root.buttons_down()
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBoxConfirm'
<InsertBoxConfirm>:
name: 'InsertBoxConfirm'
on_pre_enter:
id_chip_label.text = app.chip_value
GridLayout:
rows: 2
id: id_InsertBoxConfirm
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Label:
id: id_chip_label
text: 'valore CHIP'
GridLayout:
size_hint_y: .2
height: .15
cols: 1
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
Button:
text: 'OK'
id: button_ok
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<MyScreenManager>:
StartScreen:
id: 'StartScreen'
name: 'StartScreen'
InsertBox:
id: InsertBox
name: 'InsertBox'
InsertBoxConfirm:
id: InsertBoxConfirm
name: 'InsertBoxConfirm'
给你:
for child in self.mydropdownsomething.children[:]:
self.mydropdownsomething.remove_widget(child)
其中 mydropdownsomething 是您动态添加下拉按钮的对象。
有关详细信息,请参阅概述、片段和示例。
概述
kv 文件
- 删除导入语句,
#:import Factory kivy.factory.Factory
- 将
root.reset_chip_list()
从on_enter:
移动到on_leave:
- 用新的回调方法替换
Factory.CustomDropDownChip().open(self)
,root.create_open_customdropdown(self)
- 从
on_press:
后退按钮中删除root.reset_chip_list()
因为当我们离开屏幕时,它会自动触发on_leave:
事件。 - 将
app.chip_value
替换为root.manager.chip_value
因为我们会将变量chip_value
从 App class 移动到根 class.
片段 - kv 文件
Button:
id: id_chip
text: 'Select chip'
spacing: 5
on_release:
root.create_open_customdropdown(self)
Python代码
- 添加导入语句,
from kivy.properties import BooleanProperty, ObjectProperty
- 从
class InsertBox(Screen):
中删除变量(全局chip_list;全局chip_list_empty;全局connected_flag)
- 将
chip_list = []
替换为chip_list = ListProperty([])
;chip_list_empty = []
与chip_list_empty = ListProperty([])
;并添加connected_flag = BooleanProperty(False)
- 在
class InsertBox(Screen):
的 class 级别添加 ObjectProperty,dropdown = ObjectProperty(None)
以便我们可以使用它连接到 CustomDropDownChip 对象并将其删除。 - 实现一个新方法,create_open_customdropdown(self, instance): inside
class InsertBox(Screen):
- 在方法中,将
chip_list
替换为self.chip_list
;chip_list_empty
与self.chip_list_empty
;connected_flag
和self.connected_flag
- 从
class testdropdownApp():
中删除 - 将
chip_value = ''
从class testdropdownApp()
移动到class MyScreenManager():
- 在
SetChip()
方法中,将pass
替换为self.chip_value = value
- 在CustomDropDownChip的构造函数中,添加
chip_list
作为参数;删除notes = chip_list
;并将notes
替换为chip_list
chip_list = chip_list_empty
代码段 - Python 代码
class CustomDropDownChip(DropDown):
def __init__(self, chip_list, **kwargs):
super(CustomDropDownChip, self).__init__(**kwargs)
for note in chip_list:
btn = Button(text='%s' % note, size_hint_y=None, height=int(Window.height)/10)
btn.bind(on_release=lambda btn: self.select('CHIP: ' + btn.text))
self.add_widget(btn)
...
class InsertBox(Screen):
consommables = ListProperty([])
chip_list = ListProperty([])
chip_list_empty = ListProperty([])
connected_flag = BooleanProperty(False)
dropdown = ObjectProperty(None)
def create_open_customdropdown(self, instance):
self.dropdown = CustomDropDownChip(self.chip_list)
self.dropdown.open(instance)
...
def reset_chip_list(self):
print("\tlen(chip_list)=", len(self.chip_list))
self.chip_list = self.chip_list_empty
print("\tlen(chip_list)=", len(self.chip_list))
if self.dropdown is not None:
self.remove_widget(self.dropdown)
例子
main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.core.window import Window
from datetime import time
from threading import Thread
import paho.mqtt.client as mqtt
import time
from time import sleep
from kivy.factory import Factory
from kivy.clock import Clock
from kivy.properties import BooleanProperty, ListProperty, ObjectProperty
MAX_TIME = 1/60.
class CustomDropDownChip(DropDown):
def __init__(self, chip_list, **kwargs):
super(CustomDropDownChip, self).__init__(**kwargs)
for note in chip_list:
btn = Button(text='%s' % note, size_hint_y=None, height=int(Window.height)/10)
btn.bind(on_release=lambda btn: self.select('CHIP: ' + btn.text))
self.add_widget(btn)
class StartScreen(Screen):
pass
class InsertBox(Screen):
consommables = ListProperty([])
chip_list = ListProperty([])
chip_list_empty = ListProperty([])
connected_flag = BooleanProperty(False)
dropdown = ObjectProperty(None)
def create_open_customdropdown(self, instance):
self.dropdown = CustomDropDownChip(self.chip_list)
self.dropdown.open(instance)
def buttons_down(self):
app = App.get_running_app()
app.InsertSelection = 'InsertBoxConfirm'
def on_connect(self, mqttc, obj, flags, rc):
if rc==0:
mqttc.connected_flag = True
self.connected_flag = True
print("connected OK")
else:
print("Bad connection Returned code=",rc)
def on_disconnect(self, mqttc, obj, rc):
pass
def on_message(self, mqttc, obj, msg):
response = str(msg.payload)
if response not in self.chip_list:
sleep(1)
self.chip_list.append(response)
if mqttc.connected_flag == False:
mqttc.on_disconnect()
def on_publish(self, mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(self, mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(self, mqttc, obj, level, string):
print(string)
def __init__(self, **kwargs):
super(InsertBox, self).__init__(**kwargs)
def stop_mqtt(self):
mqttc.disconnect()
def start_mqtt(self):
self.read_chip()
def read_chip(self, *args):
global t
t = Thread(target=self.read_).start()
def read_(self):
mqtt.Client.connected_flag = False # create flag in class
self.connected_flag = False
global mqttc
mqttc = mqtt.Client(transport="websockets")
mqttc.on_message = self.on_message
mqttc.on_connect = self.on_connect
mqttc.on_publish = self.on_publish
mqttc.on_subscribe = self.on_subscribe
mqttc.on_log = self.on_log
mqttc.connect("test.mosquitto.org", 8080, 60)
mqttc.subscribe("temp/random", 0)
mqttc.loop_forever()
def consume(self, *args):
while self.consommables and time() < (Clock.get_time() + MAX_TIME):
item = self.consommables.pop(0) # i want the first one
label = Factory.MyLabel(text=item)
self.root.ids.id_chip.text = label #add_widget(label)
# @classmethod
def reset_chip_list(self):
print("\tlen(chip_list)=", len(self.chip_list))
self.chip_list = self.chip_list_empty
print("\tlen(chip_list)=", len(self.chip_list))
if self.dropdown is not None:
self.remove_widget(self.dropdown)
class InsertBoxConfirm(Screen):
def buttons_set(self):
InsertBox.buttons_set()
def buttons_reset(self):
InsertBox.buttons_reset()
class MyScreenManager(ScreenManager):
chip_value = ''
def SetChip(self, value):
self.chip_value = value
class testdropdownApp(App):
title = "Kivy Drop-Down List Demo"
def build(self):
return MyScreenManager()
def on_stop(self):
self.root.ids.InsertBox.stop_mqtt()
if __name__ == '__main__':
testdropdownApp().run()
testdropdown.kv
#:kivy 1.11.0
<CustomDropDownChip>:
on_select:
app.root.ids.InsertBox.ids.id_chip.text = '{}'.format(args[1])
app.root.SetChip(args[1])
<StartScreen>:
name: 'StartScreen'
Button:
text: 'Start'
on_release:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<InsertBox>:
name: 'InsertBox'
id: test00
on_enter:
root.start_mqtt()
on_leave:
root.stop_mqtt()
root.reset_chip_list()
GridLayout:
rows: 2
id: test01
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Button:
id: id_chip
text: 'Select chip'
# size_hint_y: .5
spacing: 5
on_release:
root.create_open_customdropdown(self)
GridLayout:
size_hint_y: .2
height: .15
cols: 2
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
# height: .15
Button:
text: "Back"
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'StartScreen'
Button:
text: 'OK'
on_press:
root.buttons_down()
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBoxConfirm'
<InsertBoxConfirm>:
name: 'InsertBoxConfirm'
on_pre_enter:
id_chip_label.text = root.manager.chip_value
GridLayout:
rows: 2
id: id_InsertBoxConfirm
GridLayout:
rows: 1
size_hint_y: .27
padding: 5
Label:
id: id_chip_label
text: 'valore CHIP'
GridLayout:
size_hint_y: .2
height: .15
cols: 1
BoxLayout:
padding: 5
orientation: 'horizontal'
size: root.size
pos: root.pos
spacing: 5
Button:
text: 'OK'
id: button_ok
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 0
root.manager.current = 'InsertBox'
<MyScreenManager>:
StartScreen:
id: 'StartScreen'
name: 'StartScreen'
InsertBox:
id: InsertBox
name: 'InsertBox'
InsertBoxConfirm:
id: InsertBoxConfirm
name: 'InsertBoxConfirm'