FloatLayout中的kivy下拉菜单不显示GridLayout

问题描述 投票:0回答:2

[尝试使用下拉按钮创建应用的人,但似乎无法正常工作(完整的应用具有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!"

enter image description here

python drop-down-menu kivy dropdown
2个回答
0
投票

问题是您正在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_hintsize参数,这些参数已创建为允许Buttons调整大小的GridLayout。我也注释掉了一些不必要的代码。


0
投票

大主按钮在我运行您的代码时出现(必须添加App类),并且按预期工作。但是Buttonlight.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文本的宽度扩大了。

© www.soinside.com 2019 - 2024. All rights reserved.