【问题标题】:remove border and add multilevel submenu删除边框并添加多级子菜单
【发布时间】:2017-11-04 16:27:23
【问题描述】:

test.py

import kivy
kivy.require('1.10.0')

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

from kivy.core.window import Window



class CustDrop(DropDown):
    def __init__(self, **kwargs):
        super(CustDrop, self).__init__( **kwargs)
        self.select('')




class ExampleApp(App):
    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root


if __name__ =='__main__':
    ExampleApp().run()

test.kv

BoxLayout:
    orientation: 'vertical'
    #spacing : 10
    BoxLayout:
        #spacing : 10
        canvas.before:
            Rectangle:
                pos: self.pos
                size: self.size

            #Color:
                #rgb: (70,70,70)

        size_hint_y:1
        Button:
            spacing : 10
            text: 'test1'
            size : (60,30)
            size_hint : (None, None)
            background_color: 90 , 90, 90, 90
            color: 0, 0.517, 0.705, 1



        Button:
            text: 'test2'
            size: (60, 30)
            size_hint: (None, None)
            background_color: 90 , 90, 90, 90
            color: 0, 0.517, 0.705, 1

        Button:
            id: btn
            text: 'test3'
            size: (60, 30)
            size_hint: (None, None)
            on_release: dropdown.open(self)
            #size_hint_y: None
            #height: '40dp'
            background_color: 90 , 90, 90, 90
            color: 0, 0.517, 0.705, 1

        CustDrop:

            id: dropdown

            Button:
                text: 'Sub menu1 Test3'
                size_hint_y: None
                height: '30dp'
                #on_release: dropdown.select('')
                on_release: app.root.test
                background_color: 90 , 90, 90, 90
                color: 0, 0.517, 0.705, 1

            Button:
                text: 'Sub menu2 Test3'
                size_hint_y: None
                height: '30dp'
                on_release: dropdown.select('')
                background_color: 90 , 90, 90, 90
                color: 0, 0.517, 0.705, 1


            Button:
                text: 'Sub menu3 Test3'
                size_hint_y: None
                height: '30dp'
                on_release: dropdown.select('')
                background_color: 90 , 90, 90, 90
                color: 0, 0.517, 0.705, 1

            Button:
                text: 'Fourth'
                size_hint_y: None
                height: '30dp'
                on_release: dropdown.select('')
                background_color: 90 , 90, 90, 90
                color: 0, 0.517, 0.705, 1

    BoxLayout:

        canvas.before:
            Rectangle:
                pos: self.pos
                size: self.size

            Color:
                rgb: (1,1,1)

        AsyncImage
            source: '2.jpg'

        AsyncImage
            source: '4.jpg'

        AsyncImage
            source: '2.jpg'

        Label:
            size_hint_x: 22

    Label:
        size_hint_y: 18
  1. 我希望菜单中只有右边框 (Test1,Test2,Test3)
  2. 点击“Test3”菜单时显示子菜单。我想增加子菜单的宽度,所有菜单都应左对齐。
  3. 如何在 Test3 菜单中添加多级子菜单
  4. 在第二行缩小图像 4.jpg 和 2.jpg 之间的空间

【问题讨论】:

    标签: python python-2.7 kivy kivy-language


    【解决方案1】:

    我希望菜单中只有右边框 (Test1,Test2,Test3)

    您可以将每个 background_normal 设置为 '',然后在其画布中自己绘制边框

    当点击“Test3”菜单然后显示子菜单。我想增加子菜单的宽度,所有菜单都应该左对齐。

    您必须将DropDownauto_width 属性设置为False,然后设置您想要的width

    如何在Test3菜单中添加多级子菜单

    与第一个一样,您必须将另一个 DropDown 附加到 DropDown 的一个孩子

    在第二行缩小图像 4.jpg 和 2.jpg 之间的空间

    你只需要设置BoxLayoutspacing

    以下是您的所有请求的代码:

    BoxLayout:
        orientation: 'vertical'
        #spacing : 10
        BoxLayout:
            #spacing : 10
            canvas.before:
                Rectangle:
                    pos: self.pos
                    size: self.size
    
                #Color:
                    #rgb: (70,70,70)
    
            size_hint_y:1
            Button:
                canvas:
                    Color:
                        rgb: 0,0,0
                    Line:
                        points: self.pos[0] + self.size[0], self.pos[1], self.pos[0] + self.size[0], self.pos[1] + self.size[1]
                        width: 1.5
                spacing : 10
                text: 'test1'
                size : (60,30)
                size_hint : (None, None)
                background_normal: ''
                background_color: 90 , 90, 90, 90
                color: 0, 0.517, 0.705, 1
    
    
    
            Button:
                canvas:
                    Color:
                        rgb: 0,0,0
                    Line:
                        points: self.pos[0] + self.size[0], self.pos[1], self.pos[0] + self.size[0], self.pos[1] + self.size[1]
                        width: 1.5
                text: 'test2'
                size: (60, 30)
                size_hint: (None, None)
                background_color: 90 , 90, 90, 90
                background_normal: ''
                color: 0, 0.517, 0.705, 1
    
            Button:
    
                id: btn
                text: 'test3'
                size: (60, 30)
                size_hint: (None, None)
                on_release: dropdown.open(self)
                #size_hint_y: None
                #height: '40dp'
                background_normal: ''
                background_color: 90 , 90, 90, 90
                color: 0, 0.517, 0.705, 1
    
            CustDrop:
                auto_width: False
                size_hint_x: None
                width: '250dp'
                id: dropdown
                BoxLayout:
                    size_hint_y: None
                    height: '30dp'
                    Button:
                        text: 'Sub menu1 Test3'
                        size_hint_x: None
                        width: '125dp'
                        #on_release: dropdown.select('')
                        on_release: app.root.test
                        background_color: 90 , 90, 90, 90
                        color: 0, 0.517, 0.705, 1
                    Button:
                        background_color: 0,0,0,0
                        width: '125dp'
                BoxLayout:
                    size_hint_y: None
                    height: '30dp'
                    Button:
                        text: 'Sub menu2 Test3'
                        size_hint_x: None
                        width: '125dp'
                        on_release: dropdown.select('')
                        background_color: 90 , 90, 90, 90
                        color: 0, 0.517, 0.705, 1
                    Button:
                        background_color: 0,0,0,0
                        width: '125dp'
                BoxLayout:
                    size_hint_y: None
                    height: '30dp'
                    Button:
                        text: 'Sub menu3 Test3'
                        size_hint_x: None
                        width: '125dp'
                        on_release: dropdown.select('')
                        background_color: 90 , 90, 90, 90
                        color: 0, 0.517, 0.705, 1
                    Button:
                        background_color: 0,0,0,0
                        width: '125dp'
                BoxLayout:
                    size_hint_y: None
                    height: '30dp'
                    Button:
                        text: 'Fourth'
                        size_hint_x: None
                        width: '125dp'
                        on_release: dropdown2.open(d2)
                        background_color: 90 , 90, 90, 90
                        color: 0, 0.517, 0.705, 1
                    Button:
                        id: d2
                        background_color: 0,0,0,0
                        size_hint_x: None
                        width: self.parent.width/2.0
                    CustDrop:
                        auto_width: False
                        size_hint_x: None
                        width: '125dp'
                        id: dropdown2
                        Button:
                            text: 'Sub menu1 Test3'
                            size_hint_y: None
                            height: '30dp'
                            #on_release: dropdown2.select('')
                            on_release: app.root.test
                            background_color: 90 , 90, 90, 90
                            color: 0, 0.517, 0.705, 1
    
                        Button:
                            text: 'Sub menu2 Test3'
                            size_hint_y: None
                            height: '30dp'
                            on_release: dropdown2.select('')
                            background_color: 90 , 90, 90, 90
                            color: 0, 0.517, 0.705, 1
    
    
                        Button:
                            text: 'Sub menu3 Test3'
                            size_hint_y: None
                            height: '30dp'
                            on_release: dropdown2.select('')
                            background_color: 90 , 90, 90, 90
                            color: 0, 0.517, 0.705, 1
    
        BoxLayout:
            spacing: 0,0
            canvas.before:
                Rectangle:
                    pos: self.pos
                    size: self.size
    
                Color:
                    rgb: (1,1,1)
    
            AsyncImage
                source: '2.jpg'
    
            AsyncImage
                source: '4.jpg'
    
            AsyncImage
                source: '2.jpg'
    
            Label:
                size_hint_x: 22
    
        Label:
            size_hint_y: 18
    

    更新在前面添加子子菜单

    为此,我将子菜单的每个按钮都放在框中,我在同一个框中添加了另一个不可见按钮,它是附加到子子菜单的不可见按钮

    我希望这会有所帮助!

    【讨论】:

    • 感谢您的回复。您能再帮我一个忙吗?当我点击第四个然后子菜单显示在第四个菜单下。如何在第四个前面显示
    • @yashkumar 当然可以,但是由于 kivy 没有计划这种行为,我们必须稍微作弊,我会用它来更新我的代码
    【解决方案2】:

    详情请参考以下解释、解决方案和示例。

    按钮 - 边框

    边框信息采用格式(下、右、上、左)。每个值都以像素为单位。边框默认为 (16, 16, 16, 16)。在 kv 文件中使用以下内容:

    菜单 - 右边框打开

    border: (0, 16, 0, 0)
    

    子菜单 - 所有边框关闭

    border: (0, 0, 0, 0)
    

    下拉宽度

    默认情况下,下拉菜单的宽度将与附加小部件的宽度相同。如果您想提供自己的宽度,请将 auto-width 设置为 False。在 kv 文件中使用以下内容。

    增加下拉菜单宽度

    auto-width: False
    width: 150
    

    文本对齐 - 按钮/标签

    默认情况下,文本图像(纹理)仅足够大以包含字符并位于中心。 valign 属性将不起作用,并且 halign 只有在您的文本有换行符时才会起作用;即使 halign 设置为 left(默认情况下),单行文本也会显示为居中。

    为了使对齐属性生效,请设置 text_size,它指定文本对齐的边界框的大小。例如,以下代码将此大小绑定到按钮/标签的大小,因此文本将在小部件边界内对齐。这也将自动换行按钮/标签的文本以保留在该区域内。

    padding_x 是小部件框内文本的水平填充。默认为 0。以下代码的值为 5,以便文本不靠近右边框。

    左对齐

    text_size: self.size
    valign: "middle"
    padding_x: 5
    

    图片 - 缩小空间

    AsyncImage 表示异步加载图像。它可以防止您的应用程序等到图像加载完毕。如果您想显示大图像或从 URL 中检索它们,使用 AsyncImage 将允许在后台线程上检索这些资源,而不会阻塞您的应用程序。

    例如,如果您希望您的图像靠近它之前的图像,您可以执行以下操作:

    AsyncImage:
        canvas:
            Rectangle:
                texture: CoreImage("linux.png").texture
                size: self.width, self.height
                pos: self.x - 8, self.y
    

    按钮/标签 - 重复设置

    不必为每个按钮/标签重复相同的值,我们可以使用模板来代替,如下所示。动态类,仅由该规则的声明创建,继承自 Button 类,允许我们更改默认值并为其所有实例创建绑定,而无需在 Python 端添加任何新代码。

    模板

        <DropdownButton@Button>:
            border: (0, 16, 0, 16)
            text_size: self.size
            valign: "middle"
            padding_x: 5
            size_hint_y: None
            height: '30dp'
            on_release: app.root.test
            background_color: 90 , 90, 90, 90
            color: 0, 0.517, 0.705, 1
    
        <MenuButton@Button>:
            text_size: self.size
            valign: "middle"
            padding_x: 5
            size : (60,30)
            size_hint : (None, None)
            background_color: 90 , 90, 90, 90
            color: 0, 0.517, 0.705, 1
            border: (0, 16, 0, 0)
    
    <CustDrop>:
        auto_width: False
        width: 150
        DropdownButton:
            text: 'Sub menu1 Test3'
    
        DropdownButton:
            text: 'Sub menu2 Test3'
    
    BoxLayout:
        orientation: 'vertical'
    
        BoxLayout:
            MenuButton:
                text: 'test1'
    
            MenuButton:
                text: 'test2'
    
            MenuButton:
                id: btn
                text: 'test3'
                on_release: dropdown.open(self)
    

    示例

    main.py

    ​​>
    from kivy.app import App
    from kivy.uix.dropdown import DropDown
    from kivy.lang import Builder
    
    
    class CustDrop(DropDown):
        def __init__(self, **kwargs):
            super(CustDrop, self).__init__(**kwargs)
            self.select('')
    
    
    class ExampleApp(App):
        def build(self):
            self.root = Builder.load_file('main.kv')
            return self.root
    
    
    if __name__ == '__main__':
        ExampleApp().run()
    

    main.kv

    #:kivy 1.10.0
    #:import CoreImage kivy.core.image.Image
    
    <DropdownButton@Button>:
        border: (0, 16, 0, 16)
        text_size: self.size
        valign: "middle"
        padding_x: 5
        size_hint_y: None
        height: '30dp'
        #on_release: dropdown.select('')
        on_release: app.root.test
        background_color: 90 , 90, 90, 90
        color: 0, 0.517, 0.705, 1
    
    
    <CustDrop>:
        auto_width: False
        width: 150
        DropdownButton:
            text: 'Sub menu1 Test3'
    
        DropdownButton:
            text: 'Sub menu2 Test3'
    
        DropdownButton:
            text: 'Sub menu3 Test3'
    
        DropdownButton:
            text: 'Fourth'
    
    
    <MenuButton@Button>:
        text_size: self.size
        valign: "middle"
        padding_x: 5
        size : (60,30)
        size_hint : (None, None)
        background_color: 90 , 90, 90, 90
        color: 0, 0.517, 0.705, 1
        border: (0, 16, 0, 0)
    
    
    BoxLayout:
        orientation: 'vertical'
        #spacing : 10
    
        BoxLayout:
            canvas.before:
                Rectangle:
                    pos: self.pos
                    size: self.size
    
            size_hint_y: 1
    
            MenuButton:
                text: 'test1'
    
            MenuButton:
                text: 'test2'
    
            MenuButton:
                id: btn
                text: 'test3'
                on_release: dropdown.open(self)
    
            CustDrop:
                id: dropdown
    
        BoxLayout:
            canvas.before:
                Rectangle:
                    pos: self.pos
                    size: self.size
    
                Color:
                    rgb: (1,1,1)
    
            AsyncImage:
                source: "linux.png"     # '2.jpg'
    
            AsyncImage:
                source: "macosx.png"    # '4.jpg'
    
            AsyncImage:
                canvas:
                    Rectangle:
                        texture: CoreImage("linux.png").texture    # '2.jpg'
                        size: self.width, self.height
                        pos: self.x - 8, self.y
    
            Label:
                size_hint_x: 22
    
        Label:
            size_hint_y: 18
    

    输出

    【讨论】:

    • MenuButton: id: btn4 text: 'test4' on_release: dropdown2.open(self) CustDrop: id: dropdown2 : id: dropdown2 auto_width: False width: 150 DropdownButton: text: 'test1 ' DropdownButton: text: 'test2' DropdownButton: text: 'test3' DropdownButton: text: 'test4' 你能再帮我一个忙吗?我在上面的代码中创建了一个带有子菜单的菜单。但它不能正常工作以及如何在“Sub menu1 Test3”下使用导航图像再添加一个级别。 test3>子菜单1 Test3>第三级子菜单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2016-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多