【发布时间】:2015-12-04 06:29:51
【问题描述】:
我想在 Kivys ScreenManager 管理的第二个屏幕中生成一个下拉列表。如果我这样做,我会得到这个回溯:
...
File "C:/Users/ORANG/PycharmProjects/waldi/playground/cw.py", line 76, in on_text
instance.drop_down.open(instance)
File "C:\Kivy-1.9.0-py2.7-win32-x64\kivy27\kivy\uix\dropdown.py", line 215, in open
'Cannot open a dropdown list on a hidden widget')
kivy.uix.dropdown.DropDownException: Cannot open a dropdown list on a hidden widget
这是代码,和this中的基本相同 example,只是嵌入到屏幕管理器场景中,非常简单:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.properties import ListProperty, StringProperty
import re
from kivy.lang import Builder
Builder.load_string('''
<Lieferant>:
ComboLayout:
Label:
text: 'Label'
ComboEdit:
size_hint: .5, .3
pos_hint: {'center':(.5, .5)}
# `args` is the keyword for arguments passed to `on_text` in kv language
on_text: self.parent.on_text(self, args[1])
''')
class ComboEdit(TextInput):
"""
This class defines a Editable Combo-Box in the traditional sense
that shows it's options
"""
options = ListProperty(('',))
'''
:data:`options` defines the list of options that will be displayed when
touch is released from this widget.
'''
def __init__(self, **kw):
ddn = self.drop_down = DropDown()
ddn.bind(on_select=self.on_select)
super(ComboEdit, self).__init__(**kw)
def on_options(self, instance, value):
ddn = self.drop_down
# clear old options
ddn.clear_widgets()
for option in value:
# create a button for each option
but = Button(text=option,
size_hint_y=None,
height='36sp',
# and make sure the press of the button calls select
# will results in calling `self.on_select`
on_release=lambda btn: ddn.select(btn.text))
ddn.add_widget(but)
def on_select(self, instance, value):
# on selection of Drop down Item... do what you want here
# update text of selection to the edit box
self.text = value
class ComboLayout(BoxLayout):
rtsstr = StringProperty("".join(("Substrate1,,,Substrate1,,,Substrate1,,,",
"Substrate1,,,Substrate1,,,Substrate_coating",
",,,silicon,,,silicon_Substrate,,,substrate_",
"silicon,,,")))
def on_text(self, instance, value):
if value == '':
instance.options = []
else:
match = re.findall("(?<=,{3})(?:(?!,{3}).)*?%s.*?(?=,{3})" % value, \
self.rtsstr, re.IGNORECASE)
# using a set to remove duplicates, if any.
instance.options = list(set(match))
instance.drop_down.open(instance)
class Intro(Screen):
pass
class Lieferant(Screen):
pass
class CWApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(Intro(name='Intro'))
sm.add_widget(Lieferant(name='Lieferant'))
return sm
if __name__ == '__main__':
CWApp().run()
可以合并吗?你会怎么做? 如果我只是将这一行注释掉,这段代码就会运行,这会在屏幕之前添加一个屏幕,并带有下拉菜单:
sm.add_widget(Intro(name='Intro'))
【问题讨论】: