[尝试使用下拉按钮创建应用的人,但似乎无法正常工作(完整的应用具有7行GridLayout,示例中的FloatLayout是其中的一行)我尝试了GridLayout,BoxLayout和FloatLayout,仍然没有出现在应用程序上。有什么主意吗?
。py文件
class WindowManager(ScreenManager, Screen):
TestMe = ObjectProperty(None)
text_lists = ['hi', 'nice one', 'another one']
class TestMe(Screen, FloatLayout):
global text_lists
main_button = ObjectProperty(None)
selected_list = 'SELECTED'
top_layout = ObjectProperty(None)
top_layout = GridLayout(cols=4)
def __init__(self, **kwargs):
super(TestMe, self).__init__(**kwargs)
self.dropdown = DropDown()
self.create_drop_down()
self.create_go_button()
def create_drop_down(self):
for list_name in text_lists:
# When adding widgets, we need to specify the height manually
# (disabling the size_hint_y) so the dropdown can calculate
# the area it needs.
btn = Button(text= list_name, size_hint_y=None, height=88, width=400, background_color=(41/255, 21/255, 228/255, 1))
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: self.dropdown.select(btn.text),
on_press=lambda btn: self.select_list(btn.text))
# then add the button inside the dropdown
self.dropdown.add_widget(btn)
# create a big main button
self.main_button = Button(text='Choose A List', size_hint=(None, None), height=88, width=400, background_color=(41/255, 21/255, 228/255, 1))
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
self.main_button.bind(on_release=self.dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
self.dropdown.bind(on_select=lambda instance, x: setattr(self.main_button, 'text', x))
self.top_layout.add_widget(self.main_button)
def create_go_button(self):
go_btn = Button(text="Go!", size_hint=(None, None), height=88, width=400, background_color=(41/255, 21/255, 228/255, 1))
self.top_layout.add_widget(go_btn)
def select_list(self, selected):
self.selected_list = selected
class MyTest(App):
def build(self):
return kv
if __name__ == '__main__':
kv = Builder.load_file('test_kv.kv')
MyTest().run()
test_kv.kv文件
WindowManager:
TestMe:
<TestMe>:
name: "testy"
id: testy
top_layout: top_layout
FloatLayout:
Label:
text: 'Test Screen'
font: 'Aharoni'
font_size: 24
pos_hint: {"left": 0.45, "y": 0.45}
GridLayout:
pos_hint: {"top": 0.9}
size_hint: 1, 0.8
rows: 2
spacing: 10
padding: 10
GridLayout:
id: top_layout
cols: 4
Button:
text: "Fun!"
Label:
text: "This is a test"
Button:
text: "Run!"
问题是您正在create_drop_down()
类的create_go_button()
方法中调用__init__()
和TestMe
。由于您还在<TestMe>:
中定义了kv
规则,因此存在冲突。根据不太清晰的documentation,在运行kv
之后将应用__init__()
规则。这意味着在其Widgets
中添加到TestMe
的任何__init__()
将被Widegets
规则中指定的kv
覆盖。可能的解决方案是在TestMe
方法或__init__()
方法中添加kv
的所有子级,或将Widgets
的添加项移出__init__()
方法。这是使用后一种方法的代码的修改版本:
class WindowManager(ScreenManager, Screen):
TestMe = ObjectProperty(None)
text_lists = ['hi', 'nice one', 'another one']
class TestMe(Screen, FloatLayout):
global text_lists
main_button = ObjectProperty(None)
selected_list = 'SELECTED'
top_layout = ObjectProperty(None)
#top_layout = GridLayout(cols=4)
def __init__(self, **kwargs):
super(TestMe, self).__init__(**kwargs)
self.dropdown = DropDown()
Clock.schedule_once(self.create_drop_down)
Clock.schedule_once(self.create_go_button)
# self.create_drop_down()
# self.create_go_button()
def create_drop_down(self, *args):
for list_name in text_lists:
# When adding widgets, we need to specify the height manually
# (disabling the size_hint_y) so the dropdown can calculate
# the area it needs.
btn = Button(text= list_name, size_hint_y=None, height=88, width=400, background_color=(41/255, 21/255, 228/255, 1))
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: self.dropdown.select(btn.text),
on_press=lambda btn: self.select_list(btn.text))
# then add the button inside the dropdown
self.dropdown.add_widget(btn)
# create a big main button
# self.main_button = Button(text='Choose A List', size_hint=(None, None), height=88, width=400, background_color=(41/255, 21/255, 228/255, 1))
self.main_button = Button(text='Choose A List', background_color=(41/255, 21/255, 228/255, 1))
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
self.main_button.bind(on_release=self.dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
self.dropdown.bind(on_select=lambda instance, x: setattr(self.main_button, 'text', x))
self.top_layout.add_widget(self.main_button)
def create_go_button(self, *args):
# go_btn = Button(text="Go!", size_hint=(None, None), height=88, width=400, background_color=(41/255, 21/255, 228/255, 1))
go_btn = Button(text="Go!", background_color=(41/255, 21/255, 228/255, 1))
self.top_layout.add_widget(go_btn)
def select_list(self, selected):
self.selected_list = selected
class MyTest(App):
def build(self):
return kv
我已经修改了代码,以使用create
调用Clock.schedule_once()
方法,以便它在应用kv
规则后发生。我还删除了size_hint
和size
参数,这些参数已创建为允许Buttons
调整大小的GridLayout
。我也注释掉了一些不必要的代码。
大主按钮在我运行您的代码时出现(必须添加App
类),并且按预期工作。但是Button
与light.png
Image
一起显示在左下角。尝试稍微移动一下它,使其不与Image
重叠。像这样的东西:
self.main_button = Button(text='Choose A List', size_hint=(None, None), height=88, width=140,
background_color=(41/255, 21/255, 228/255, 1), pos_hint={'center_x':0.5, 'y':0.4})
[我也将它包含Choose A List
文本的宽度扩大了。