1

我想编写一个带有 KivyMD 的移动应用程序,例如底部表菜单。我对 KivyMD 按钮表的问题是,当我单击按钮打开它时,需要很长时间(取决于菜单长度),因为每次按下按钮时都会调用函数生成列表。所以我想为此编写自己的解决方案。在我的 kv 文件中,我手动添加了 20 个按钮来查看,一切正常。但是我没有找到在带有循环的python文件中执行此操作的方法。任何人都可以帮我添加 30 多个按钮到 modalview 以进行滚动吗?

这是我的python文件:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.core.window import Window


Builder.load_file('mylayout.kv')
Window.size = (350, 700)

class MyLayout(BoxLayout):
    pass

class MainApp(App):

    def build(self):
        return MyLayout()


MainApp().run()

我的 kv 文件:

#:import Factory kivy.factory.Factory

<MyPopup@ModalView>
    auto_dismiss: True
    size_hint: 1, 0.5
    pos_hint: {'x': 0, 'top': 0.5}
    background_color: 0,0,0,0
    background_normal: ''
    canvas.before:
        Color:
            rgba: 48/150,84/150,150/150,1
        Rectangle:
            size: self.size
            pos: self.pos
    ScrollView:
        #do_scroll_x: False
        GridLayout:
            id: container1
            cols: 1
            size_hint: None, None
            size: root.width, 1200
            pos_hint: {'center_x': .5, 'center_y': .5}

            MyButton:
                text: '1'
                on_press:
                    root.dismiss()
                    print(1)
            MyButton:
                text: '2'
                on_press:
                    root.dismiss()
                    print(2)
            MyButton:
                text: '3'
                on_press:
                    root.dismiss()
                    print(3)
            MyButton:
                text: '4'
                on_press:
                    root.dismiss()
                    print(4)
            MyButton:
                text: '5'
                on_press:
                    root.dismiss()
                    print(5)
            MyButton:
                text: '6'
                on_press:
                    root.dismiss()
                    print(6)
            MyButton:
                text: '7'
                on_press:
                    root.dismiss()
                    print(7)
            MyButton:
                text: '8'
                on_press:
                    root.dismiss()
                    print(8)
            MyButton:
                text: '9'
                on_press:
                    root.dismiss()
                    print(9)
            MyButton:
                text: '10'
                on_press:
                    root.dismiss()
                    print(10)
            MyButton:
                text: '11'
                on_press:
                    root.dismiss()
                    print(11)
            MyButton:
                text: '12'
                on_press:
                    root.dismiss()
                    print(12)
            MyButton:
                text: '13'
                on_press:
                    root.dismiss()
                    print(13)
            MyButton:
                text: '14'
                on_press:
                    root.dismiss()
                    print(14)
            MyButton:
                text: '15'
                on_press:
                    root.dismiss()
                    print(15)
            MyButton:
                text: '16'
                on_press:
                    root.dismiss()
                    print(16)
            MyButton:
                text: '17'
                on_press:
                    root.dismiss()
                    print(17)
            MyButton:
                text: '18'
                on_press:
                    root.dismiss()
                    print(18)
            MyButton:
                text: '19'
                on_press:
                    root.dismiss()
                    print(19)
            MyButton:
                text: '20'
                on_press:
                    root.dismiss()
                    print(20)

<MyLayout>
    orientation: 'vertical'
    size: root.width, root.height

    Label:
        size_hint: 1, 0.9
        text: 'main'
        font_size: 24

    Button:
        size_hint: 1, 0.1
        text: 'menu'
        font_size: 24
        on_release: Factory.MyPopup().open()

<MyButton@Button>
    background_color: 0,0,0,0
    background_normal: ''
    canvas.before:
        Color:
            rgba: (48/255,84/255,150/255,1) if self.state == 'normal' else (43/255,108/255,229/255,1)
        Rectangle:
            size: self.size
            pos: self.pos
4

1 回答 1

1

为了构建MyPopup填充MyButtons,您必须在 python 代码中定义这些类或用于Factory创建实例。这是您kv执行此操作的修改版本:

<MyPopup@ModalView>
    auto_dismiss: True
    size_hint: 1, 0.5
    pos_hint: {'x': 0, 'top': 0.5}
    background_color: 0,0,0,0
    background_normal: ''
    canvas.before:
        Color:
            rgba: 48/150,84/150,150/150,1
        Rectangle:
            size: self.size
            pos: self.pos
    ScrollView:
        #do_scroll_x: False
        GridLayout:
            id: container1
            cols: 1
            size_hint: None, None
            width: root.width
            height: self.minimum_height  # let the GridLayout set its own height as needeed
            pos_hint: {'center_x': .5, 'center_y': .5}
            
<MyLayout>
    orientation: 'vertical'
    size: root.width, root.height

    Label:
        size_hint: 1, 0.9
        text: 'main'
        font_size: 24

    Button:
        size_hint: 1, 0.1
        text: 'menu'
        font_size: 24
        # on_release: Factory.MyPopup().open()
        on_release: app.open_popup()  # call app method to build MyPopup and fill it

<MyButton@Button>
    background_color: 0,0,0,0
    background_normal: ''
    size_hint_y: None
    height: 20
    canvas.before:
        Color:
            rgba: (48/255,84/255,150/255,1) if self.state == 'normal' else (43/255,108/255,229/255,1)
        Rectangle:
            size: self.size
            pos: self.pos

请注意,GridLayout高度设置为self.minimum_height允许任意数量的MyButton孩子,并且MyButton高度设置为固定值(以便GridLayout可以计算最小高度)。此外,Factorykv.

修改后的python代码:

from kivy.app import App
from kivy.factory import Factory
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.core.window import Window

Builder.load_file('mylayout.kv')
Window.size = (350, 700)

class MyLayout(BoxLayout):
    pass

class MainApp(App):

    def build(self):
        return MyLayout()

    def open_popup(self, *args):
        # create the popup (must use Factory since MyPopup is defined in kv)
        self.popup = Factory.MyPopup()

        # fill the GridLayout
        grid = self.popup.ids.container1
        for i in range(60):
            grid.add_widget(Factory.MyButton(text=str(i), on_press=self.myButtPress))

        # open popup
        self.popup.open()

    def myButtPress(self, butt):
        print(butt.text)
        self.popup.dismiss()

MainApp().run()
于 2021-04-14T02:10:25.507 回答