是否可以将复杂的布局分类,以便在布局中重复使用?
Can a complex layout be classed so it can be used repeatedly in layout?
我有一个特定的 Boxlayout,其中包含用于连续显示值的标签;现在有几行,每一行都在一个盒子布局中。我想知道我是否可以制作包含所有标签的 boxlayout class。因此,当我转到我的 .kv 文件时,我只需调用 class 而不必重复所有参数。
编辑:我已经放置了相应的 .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 文件中,标签有 names
,我可以从 python 文件中找到它(正如您从演示中看到的那样)。现在,当 class 在 .kv 文件中实例化时,完整的布局得到 id
。问题是如何使用布局的 id
和标签的 names
更改标签的值。请记住布局将被实例化多次。
在此先感谢您提供的任何帮助。谢谢,雷。
如果我正确理解了您的问题,您只需要动态 class。使用 dynamic class,您可以创建一个带有或不带有某些属性的对象,这些属性几乎不需要进一步修改就可以使用。在 kvlang
中,构建和修改 class(之后)更加容易。
首先在 python 中创建一个具有某些确定性(此处为预定或固定数量)属性的动态 class 作为,
class MyRowBox(MDBoxLayout):
name = StringProperty("NAME")
value = StringProperty("Value")
change = StringProperty("Change")
percnt = StringProperty("Chg %")
然后在kvlang
中设计为,
<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
更新(用例):
class 在 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()
注:
- 我使用
dp
以获得更好的一致性。你可以改变它。
- 您可能不再需要 class
MyBox
。
我有一个特定的 Boxlayout,其中包含用于连续显示值的标签;现在有几行,每一行都在一个盒子布局中。我想知道我是否可以制作包含所有标签的 boxlayout class。因此,当我转到我的 .kv 文件时,我只需调用 class 而不必重复所有参数。 编辑:我已经放置了相应的 .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 文件中,标签有 names
,我可以从 python 文件中找到它(正如您从演示中看到的那样)。现在,当 class 在 .kv 文件中实例化时,完整的布局得到 id
。问题是如何使用布局的 id
和标签的 names
更改标签的值。请记住布局将被实例化多次。
在此先感谢您提供的任何帮助。谢谢,雷。
如果我正确理解了您的问题,您只需要动态 class。使用 dynamic class,您可以创建一个带有或不带有某些属性的对象,这些属性几乎不需要进一步修改就可以使用。在 kvlang
中,构建和修改 class(之后)更加容易。
首先在 python 中创建一个具有某些确定性(此处为预定或固定数量)属性的动态 class 作为,
class MyRowBox(MDBoxLayout):
name = StringProperty("NAME")
value = StringProperty("Value")
change = StringProperty("Change")
percnt = StringProperty("Chg %")
然后在kvlang
中设计为,
<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
更新(用例):
class 在 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()
注:
- 我使用
dp
以获得更好的一致性。你可以改变它。 - 您可能不再需要 class
MyBox
。