是否可以对复杂的布局进行分类,以便可以在布局中重复使用?

发布于 2025-01-11 18:22:34 字数 4952 浏览 1 评论 0原文

我有一个特定的 Boxlayout,其中包含用于连续显示值的标签;现在有几行,每行都在一个盒子布局中。我想知道是否可以制作一个包含所有标签的盒子布局类。因此,当我转到 .kv 文件时,我只需调用该类,而不必重复所有参数。 编辑:我已经放置了相应的 .KV

MDBoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: "My Stock Tickers"
        
        left_action_items: [["menu", lambda x: x]]
        type: 'top'

    MyBox:
        size_hint: None, None
        size: 400, 100
        
        pos_hint: {"center_x": 0.5}
        #elevation: 20
        padding: 25
        spacing: 25
        
        md_bg_color: [0, .7, 1, 1]

        #Widget:
            #size_hint_y : None
            #height: 10

        MDLabel:
            text: "Enter Ticker"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            

        MDTextFieldRound:
            #id: user
            width: 30
            font_size: 18
            #padding_y: 15
            spacing: '20dp'

        MDFIconButton:
            user_font_size: "15sp"
            icon: "plus"
            opposite_colors: True
            elevation: 8
            md_bg_color: 1, 0, 0, 1
            spacing: '20dp'


        MDLabel:
            id: t_price
            text: "000.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

        MDLabel:
            id: t_change
            text: "00.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

    MyBox:
        size_hint: None, None
        size: 400, 200
        md_bg_color: [0, .9, 1, 1]
        #spacing: 10
        orientation: "vertical"
        pos_hint: {"center_x": 0.5}
        


        MyBox:                                   # Title Row
            size_hint: 1, None
            height: 30

            Widget:
                size_hint_x : None
                width: 20
            MDLabel:
                #color: 72/255,89/255,89/255,1
                color: 0,0,0,1
                text: "NAME"
                
                halign: 'left'
                size_hint: None, 1
                width: 100
                

            MDLabel:
                color: (0,0,0,1)
                text: "Value"

            MDLabel:
                color: (0,0,0,1)
                text: "Change"

            MDLabel:
                color: (0,0,0,1)
                text: "Chg %"



        MyRowBox:                                                  #1st Row
            id: row1
            #self.name.text: "Dow"         ????????
            #self.value.text: "000.000"    ????????
            #self.change.text: "000.000"   ????????
            #self.percnt.text: "0.01%"     ????????

我认为可行的示例将是这样的(在 python 中):编辑:我放置了一个工作样本

from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.behaviors import RectangularElevationBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.label import MDLabel
from kivymd.uix.textfield import MDTextField
from kivymd.uix.button import MDIconButton
from kivymd.uix.widget import MDWidget

class MDFIconButton(MDIconButton):
    pass

class MyBox(MDBoxLayout):
    class update():
        pass

class MyRowBox(MDBoxLayout):
    def __init__(self, **kwargs):
        super(MyRowBox, self).__init__(**kwargs)
        size_hint= 1, None
        height= 30
        self.add_widget(MDWidget(size_hint_x= None, width= 20))
        self.name = (MDLabel( color= [72 / 255, 89 / 255, 89 / 255, 1],halign= 'left', size_hint=[None, 1],width= 100))
        self.add_widget(self.name)
        self.value = MDLabel(halign= 'left')
        self.add_widget(self.value)
        self.change = MDLabel(halign='left')
        self.add_widget(self.change)
        self.percnt = MDLabel(halign='left')
        self.add_widget(self.percnt)

        self.name.text = "Dow"
        self.value.text = "000.000"
        self.change.text = "000.000"
        self.percnt.text = "000.000"
        self.change.font_size = 12
        self.percnt.font_size = 12
        self.name.color = [72 / 255, 89 / 255, 89 / 255, 1]
        self.value.color = [0, 0, 0, 1]
        self.change.color = [0, 0, 0, 1]
        self.percnt.color = [0, 0, 0, 1]
        print(self)

class MyTextField(MDTextField):
    pass

class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "BlueGray"
        return Builder.load_file('MyStocks.kv')


MainApp().run()

事实上它不起作用。这是可以发挥作用的东西还是我太乐观了?我还需要为所有标签设置 Id。

编辑:情况是我不知道如何更新这些值。在 python 文件中,标签具有名称,我可以从 python 文件中对其进行寻址(正如您从演示中看到的那样)。现在,当在 .kv 文件中实例化该类时,将获取完整的布局和 id。问题是如何使用布局的 id 和标签的名称来更改标签的值。请记住,布局将被实例化多次。

我预先感谢您对此提供的任何帮助。谢谢,雷。

I have a specific Boxlayout that contains labels to show values in a row; now there are several rows and each is in a boxlayout. I was wondering if I could make a class of the boxlayout including all the labels. So when I go to my .kv file I just call the class and don't have to repeat all the params.
EDIT: IHAVE PLACED THE CORRESPONDING .KV

MDBoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: "My Stock Tickers"
        
        left_action_items: [["menu", lambda x: x]]
        type: 'top'

    MyBox:
        size_hint: None, None
        size: 400, 100
        
        pos_hint: {"center_x": 0.5}
        #elevation: 20
        padding: 25
        spacing: 25
        
        md_bg_color: [0, .7, 1, 1]

        #Widget:
            #size_hint_y : None
            #height: 10

        MDLabel:
            text: "Enter Ticker"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            

        MDTextFieldRound:
            #id: user
            width: 30
            font_size: 18
            #padding_y: 15
            spacing: '20dp'

        MDFIconButton:
            user_font_size: "15sp"
            icon: "plus"
            opposite_colors: True
            elevation: 8
            md_bg_color: 1, 0, 0, 1
            spacing: '20dp'


        MDLabel:
            id: t_price
            text: "000.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

        MDLabel:
            id: t_change
            text: "00.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

    MyBox:
        size_hint: None, None
        size: 400, 200
        md_bg_color: [0, .9, 1, 1]
        #spacing: 10
        orientation: "vertical"
        pos_hint: {"center_x": 0.5}
        


        MyBox:                                   # Title Row
            size_hint: 1, None
            height: 30

            Widget:
                size_hint_x : None
                width: 20
            MDLabel:
                #color: 72/255,89/255,89/255,1
                color: 0,0,0,1
                text: "NAME"
                
                halign: 'left'
                size_hint: None, 1
                width: 100
                

            MDLabel:
                color: (0,0,0,1)
                text: "Value"

            MDLabel:
                color: (0,0,0,1)
                text: "Change"

            MDLabel:
                color: (0,0,0,1)
                text: "Chg %"



        MyRowBox:                                                  #1st Row
            id: row1
            #self.name.text: "Dow"         ????????
            #self.value.text: "000.000"    ????????
            #self.change.text: "000.000"   ????????
            #self.percnt.text: "0.01%"     ????????

My example of what i thought would work would be something like this (in python): EDIT: I PLACED A WORKING SAMPLE

from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.behaviors import RectangularElevationBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.label import MDLabel
from kivymd.uix.textfield import MDTextField
from kivymd.uix.button import MDIconButton
from kivymd.uix.widget import MDWidget

class MDFIconButton(MDIconButton):
    pass

class MyBox(MDBoxLayout):
    class update():
        pass

class MyRowBox(MDBoxLayout):
    def __init__(self, **kwargs):
        super(MyRowBox, self).__init__(**kwargs)
        size_hint= 1, None
        height= 30
        self.add_widget(MDWidget(size_hint_x= None, width= 20))
        self.name = (MDLabel( color= [72 / 255, 89 / 255, 89 / 255, 1],halign= 'left', size_hint=[None, 1],width= 100))
        self.add_widget(self.name)
        self.value = MDLabel(halign= 'left')
        self.add_widget(self.value)
        self.change = MDLabel(halign='left')
        self.add_widget(self.change)
        self.percnt = MDLabel(halign='left')
        self.add_widget(self.percnt)

        self.name.text = "Dow"
        self.value.text = "000.000"
        self.change.text = "000.000"
        self.percnt.text = "000.000"
        self.change.font_size = 12
        self.percnt.font_size = 12
        self.name.color = [72 / 255, 89 / 255, 89 / 255, 1]
        self.value.color = [0, 0, 0, 1]
        self.change.color = [0, 0, 0, 1]
        self.percnt.color = [0, 0, 0, 1]
        print(self)

class MyTextField(MDTextField):
    pass

class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "BlueGray"
        return Builder.load_file('MyStocks.kv')


MainApp().run()

As it is it does not work. is this something that could be made to work or am I being too optimistic. I will also be needing to set Id's for all the labels.

EDIT: The situation is that I do not know how to update the values. In the python file the labels have names which I can address fom the python file (as you can see from the demo). Now, when the class is instantiated in the .kv file the complete layout gets and id. The question is how do I change the values of the labels using the id of the layout and the names of the labels. Bear in mind the layout will be instantiated multiple times.

I thank you in advance for any assistance on this. Thanks, Ray.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

灵芸 2025-01-18 18:22:34

如果我正确理解你的问题,你只需要一个动态课程。使用动态类,您可以创建一个具有或不具有某些属性的对象,该对象无需进一步修改即可使用。在 kvlang 中,构建和修改类更加容易(之后)。

首先在 python as 中创建一个具有某些确定性(此处为预定或固定数量)属性的动态类,

class MyRowBox(MDBoxLayout):
    name = StringProperty("NAME")
    value = StringProperty("Value")
    change = StringProperty("Change")
    percnt = StringProperty("Chg %")

然后在 kvlang as 中设计它,

<MyRowBox>:
    md_bg_color: [0.5, .7, 0.2, 1]
    size_hint_y: None
    height: "30dp"

    Widget:
        size_hint_x : None
        width: "20dp"

    MDLabel:
        color: 72/255,89/255,89/255,1
        color: 0,0,0,1
        text: root.name
        halign: 'left'
        size_hint: None, 1
        width: "100dp"

    MDLabel:
        color: (0,0,0,1)
        text: root.value

    MDLabel:
        color: (0,0,0,1)
        text: root.change

    MDLabel:
        color: (0,0,0,1)
        text: root.percnt

从而在 .kv 文件现在应该看起来像,

MDBoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: "My Stock Tickers"
        left_action_items: [["menu", lambda x: x]]
        type: 'top'

    MDBoxLayout:
        size_hint: None, None
        size: "400dp", "100dp"

        pos_hint: {"center_x": 0.5}
        #elevation: 20
        padding: 25
        spacing: 25

        md_bg_color: [0, .7, 1, 1]

        #Widget:
            #size_hint_y : None
            #height: 10

        MDLabel:
            text: "Enter Ticker"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]


        MDTextFieldRound:
            #id: user
            width: 30
            font_size: 18
            #padding_y: 15
            spacing: '20dp'

        MDFIconButton:
            user_font_size: "15sp"
            icon: "plus"
            opposite_colors: True
            elevation: 8
            md_bg_color: 1, 0, 0, 1
            spacing: '20dp'


        MDLabel:
            id: t_price
            text: "000.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

        MDLabel:
            id: t_change
            text: "00.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

    MyRowBox:    # Same class as a title row
                 # due to its initilization style.
                 # Change it if you need to.
    
    MyRowBox:
        id: row1
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"

    MyRowBox:
        id: row2
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"

    MyRowBox:
        id: row3
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"

    MyRowBox:
        id: row4
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"



<MyRowBox>:
    md_bg_color: [0.5, .7, 0.2, 1]
    size_hint_y: None
    height: "30dp"

    Widget:
        size_hint_x : None
        width: "20dp"

    MDLabel:
        color: 72/255,89/255,89/255,1
        color: 0,0,0,1
        text: root.name
        halign: 'left'
        size_hint: None, 1
        width: "100dp"

    MDLabel:
        color: (0,0,0,1)
        text: root.value

    MDLabel:
        color: (0,0,0,1)
        text: root.change

    MDLabel:
        color: (0,0,0,1)
        text: root.percnt

更新(使用案例):

这个类在 python 中的使用案例可能是这样的,

# Please add the rest / necessary blocks.

class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "BlueGray"
        self.root = Builder.load_string(kv)
        return self.root


    def on_start(self):
        box1 = self.root.ids.row1
        box2 = self.root.ids.row2
        # etc.
        for i, box in enumerate([box1, box2, ]):
            box.name = str(i+1)
            box.value = str(100+i)
            box.change = str(i)
            box.percnt = f"{i/100:0.2%}"


MainApp().run()

注意:

  1. 我使用了 dp 以获得更好的一致性。你可以改变它。
  2. 您可能不再需要 MyBox 类了。

If I understood your issues properly, you just need a dynamic class. With dynamic class you can create an object with or without some propertie(s) that can be used with little to no further modifications. In kvlang it is even easier to build and modify the class (afterwards).

First create a dynamic class with some deterministic (here, predetermined or fixed no. of) properties in python as,

class MyRowBox(MDBoxLayout):
    name = StringProperty("NAME")
    value = StringProperty("Value")
    change = StringProperty("Change")
    percnt = StringProperty("Chg %")

Then design it in kvlang as,

<MyRowBox>:
    md_bg_color: [0.5, .7, 0.2, 1]
    size_hint_y: None
    height: "30dp"

    Widget:
        size_hint_x : None
        width: "20dp"

    MDLabel:
        color: 72/255,89/255,89/255,1
        color: 0,0,0,1
        text: root.name
        halign: 'left'
        size_hint: None, 1
        width: "100dp"

    MDLabel:
        color: (0,0,0,1)
        text: root.value

    MDLabel:
        color: (0,0,0,1)
        text: root.change

    MDLabel:
        color: (0,0,0,1)
        text: root.percnt

Thus your modified code in .kv file should now look like,

MDBoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: "My Stock Tickers"
        left_action_items: [["menu", lambda x: x]]
        type: 'top'

    MDBoxLayout:
        size_hint: None, None
        size: "400dp", "100dp"

        pos_hint: {"center_x": 0.5}
        #elevation: 20
        padding: 25
        spacing: 25

        md_bg_color: [0, .7, 1, 1]

        #Widget:
            #size_hint_y : None
            #height: 10

        MDLabel:
            text: "Enter Ticker"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]


        MDTextFieldRound:
            #id: user
            width: 30
            font_size: 18
            #padding_y: 15
            spacing: '20dp'

        MDFIconButton:
            user_font_size: "15sp"
            icon: "plus"
            opposite_colors: True
            elevation: 8
            md_bg_color: 1, 0, 0, 1
            spacing: '20dp'


        MDLabel:
            id: t_price
            text: "000.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

        MDLabel:
            id: t_change
            text: "00.00"
            font_size: 15
            halign: "center"
            size_hint_y: None
            height: self.texture_size[1]
            padding_y: 10

    MyRowBox:    # Same class as a title row
                 # due to its initilization style.
                 # Change it if you need to.
    
    MyRowBox:
        id: row1
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"

    MyRowBox:
        id: row2
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"

    MyRowBox:
        id: row3
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"

    MyRowBox:
        id: row4
        name: "Dow"
        value: "000.000"
        change: "000.000"
        percnt: "0.01%"



<MyRowBox>:
    md_bg_color: [0.5, .7, 0.2, 1]
    size_hint_y: None
    height: "30dp"

    Widget:
        size_hint_x : None
        width: "20dp"

    MDLabel:
        color: 72/255,89/255,89/255,1
        color: 0,0,0,1
        text: root.name
        halign: 'left'
        size_hint: None, 1
        width: "100dp"

    MDLabel:
        color: (0,0,0,1)
        text: root.value

    MDLabel:
        color: (0,0,0,1)
        text: root.change

    MDLabel:
        color: (0,0,0,1)
        text: root.percnt

Update (usage case):

The usage case of this class in python could be like,

# Please add the rest / necessary blocks.

class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "BlueGray"
        self.root = Builder.load_string(kv)
        return self.root


    def on_start(self):
        box1 = self.root.ids.row1
        box2 = self.root.ids.row2
        # etc.
        for i, box in enumerate([box1, box2, ]):
            box.name = str(i+1)
            box.value = str(100+i)
            box.change = str(i)
            box.percnt = f"{i/100:0.2%}"


MainApp().run()

Note:

  1. I used dp for better consistency. You may change it.
  2. You perhaps need the class MyBox no more.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文