Basically I've created a toolbar with two widgets. One widget (account) should change to a new window when pressed. The other (menu) should open three buttons when it is pressed. When you press on of the three buttons it should also change to a new window.
I don't know how to implement that...
Can anyone help me?
Here's my code:
kv = """
<MenuScreen>:
name: 'mainmenu'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'background.jpg'
Screen:
BoxLayout:
orientation: 'vertical'
MDTopAppBar:
title: 'Fitness App'
left_action_items: [["menu", lambda x: app.navigation_draw()]]
right_action_items: [["account", lambda x: app.callback()]]
elevation:5
MDLabel:
text: 'hello world'
halign: 'center'
BoxLayout:
spacing: 1
orientation: "vertical"
Label:
text: "Welcome back"
font_size: 100
color : 0,0,0,1
Button:
text: 'Get Started'
font_size:100
color: 0, 0, 1, 1
background_color: 0, 0, 0, 1
size_hint: 1, 1
pos_hint: {"x":0, "top":1}
on_release:
root.manager.current = 'screen2'
root.manager.transition.direction = "left"
Button:
text: 'Leave App'
font_size: 100
color: 0, 0, 1, 1
background_color: 0, 0, 0, 1
size_hint: 1, 1
pos_hint: {"x":0, "top":0}
on_release: root.manager.current = app.exit_software()
<Screen2>:
name: 'screen2'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'background.jpg'
BoxLayout:
spacing: 1
orientation: "vertical"
ScrollView:
id: scroll_view
always_overscroll: False
BoxLayout:
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Label:
id: label
text: "Please choose your problem Area"
color : 0,0,0,1
size_hint: None, None
pos_hint: {"x":0, "top":1}
font_size: 50
size: self.texture_size
Button:
text: 'Shoulders'
font_size: 30
color : 0,0,1,1
on_release:
root.manager.current = 'shoulders'
root.manager.transition.direction = "left"
Button:
text: 'Knees'
font_size: 30
color : 0,0,1,1
background_color: 0, 0, 0, 1
size_hint_y: 1
on_release:
root.manager.current = 'knees'
root.manager.transition.direction = "left"
Button:
text: 'Back'
font_size: 30
color : 0,0,1,1
background_color: 0, 0, 0, 1
size_hint_y: 1
on_release:
root.manager.current = 'back'
root.manager.transition.direction = "left"
Button:
text: 'Back to main menu'
font_size: 30
color : 0,0,1,1
background_color: 0, 0, 0, 1
size_hint_y: 1
on_release:
root.manager.current = 'mainmenu'
root.manager.transition.direction = "right"
<Screen_shoulders>:
name: 'shoulders'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'shoulders.png'
BoxLayout:
spacing: 1
orientation: "vertical"
ScrollView:
id: scroll_view
always_overscroll: False
BoxLayout:
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Label:
id: label
text: "Choose an activity"
font_size: 50
color : 0,0,0,1
size: self.texture_size
Button:
text: 'Activity1'
font_size: 50
color : 0,0,0,1
size_hint_y: 0.3
on_release:
root.manager.current = 'shouldersActivity1'
root.manager.transition.direction = "right"
Button:
text: 'Activity2'
font_size: 50
color : 0,0,0,1
size_hint_y: 0.3
on_release: app.add_text()
Button:
text: 'Back to main menu'
font_size: 20
color : 0,0,0,1
size_hint_y: 0.1
on_release:
root.manager.current = 'screen2'
root.manager.transition.direction = "right"
ScreenManager:
id: screen_manager
MenuScreen:
id: menu_scr
Screen2:
id: scr_2
"""
class MenuScreen(Screen):
pass
class Screen2(Screen):
pass
class AddTextApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
return Builder.load_string(kv)
def add_text(self):
self.root.ids.scr_2.ids.label.text += f"Some new Text\n"
self.root.ids.scr_2.ids.scroll_view.scroll_y = 0
def callback(self, instance_action_top_appbar_button):
print(instance_action_top_appbar_button)
#staticmethod
def exit_software():
App.get_running_app().stop()
def navigation_draw(self):
# open new window
def callback(self):
# open new window
if __name__ == '__main__':
AddTextApp().run()
I don't know how to make the widgets change window when they're pressed.
I have a TextInput and a button, and my aim is to be able to select some text from the TextInput and then push a button which calls a function that prints: selection_text, selection_to, and selection_from.
However, because the TextInput is not in focus when the button is pushed, the selection is lost and the function returns nothing AND/OR incorrect values.
I have seen this line of code in similar questions but I have not been able to figure out what it is meant to do, via messing with the code or looking at the TextInput docs, since I have only seen it called from within an 'on_focus' function
Clock.schedule_once(lambda dt: new_post_input.selection_text)
I have not been able to recreate the issue in an example program yet since it works when I have taken the widgets into their own program
main.py
from kivy.app import App
from kivy.properties import BooleanProperty, StringProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.modules import inspector
from kivy.core.window import Window
class NewPost(FloatLayout):
buttons_disabled = BooleanProperty(False)
cancle_button_disabled = BooleanProperty(True)
preview_text = StringProperty()
def make_bold(self, new_post_input, selected):
print('Selected = ' + selected)
print('Button has been pushed')
def preview_post(self, Button, cancleButton, TextInput, Label):
#self.preview_text = ('Hello\n' + TextInput.text)
self.buttons_disabled = True
self.cancle_button_disabled = False
Label.opacity = 1
Label.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
TextInput.opacity = 0
cancleButton.opacity = 1
cancleButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
#print(TextInput.text)
def back_from_preview(self, Button, previewButton, TextInput, Label):
self.buttons_disable = False
self.cancle_button_disabled = True
Label.opacity = 0
Label.pos_hint = {'center_x': 0.5, 'center_y': -1}
TextInput.opacity = 1
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
previewButton.opacity = 1
previewButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
class SelectionApp(App):
def build(self):
inspector.create_inspector(Window, SelectionApp)
SelectionApp().run()
selection.kv
PageLayout:
Label:
text: 'Swipe to the next page'
font_size: dp(50)
Label:
text: 'And again'
canvas.before:
Color:
rgba: (0,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
NewPost:
id: new_post
canvas.after:
Color:
rgba: 0,1,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
id: main_new_post
orientation: 'vertical'
padding: '10dp', '16dp'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
AnchorLayout:
size_hint: 1, .05
anchor_x: 'right'
anchor_y: 'center'
Label:
text: 'New Post'
size_hint: None, None
size: '100dp', '30dp'
color: .8, 0, 0, 1
font_size: '16dp'
#pos_hint: {'center_x': 0.8, 'center_y': 0.5}
Label:
size_hint: 1, .035
text: ''
font_size: '1dp'
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .38
FloatLayout:
TextInput:
id: new_post_input
#disabled: new_post.buttons_disabled
opacity: 1
background_color: 0, 0, 0, 1
foreground_color: 1, 1, 1, 1
background_disable_normal: True
multiline: True
font_size: '15dp'
padding: '10dp', '10dp'
selection_color: (.8, 0, 0, .5)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
allow_copy: True
#on_focus: new_post.on_focus(self)
canvas.after:
Color:
rgba: 1,1,1,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
orientation: 'vertical'
id: preview_new_post_label
opacity: 0
pos_hint: {'center_x': 0.5, 'center_y': -1}
canvas.before:
Color:
rgba: (.8,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
canvas:
Color:
rgba:0.8,0,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(5))
ScrollView:
always_overscroll: False
bar_color: (0,0,0,0)
Label:
text: ('Someone:\n' + new_post_input.text)
padding: "10dp", "12dp"
size_hint: None, None
height: self.texture_size[1]
width: self.parent.width
font_size: "12dp"
text_size: self.width, None
color: 0,0,0,1
multiline: True
markup: True
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Text Modification'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selection_text)
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
#padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Post Category'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
ToggleButton:
text: "Opinion"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.update_catagory(self, 'opinions')
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
Demo program working: YouTube link
Thank you for any suggestions/solutions :)
Update
It turns out that the selection seems to stop working when the TextInput is within a PageLayout with more than 2 pages in it, (Which it is in my program).
I have created a rough demo program to show the problem and have put it in .py and .kv
You can achieve that by creating a custom TextInput instance and overriding one of its method.
class MyTextInput(TextInput):
selected_text = StringProperty("")
# Use this prop. instead of 'selection_text'.
def cancel_selection(self):
self.selected_text = self.selection_text
super().cancel_selection()
Now use this instance and the new property wherever you need.
In .kv,
FloatLayout:
MyTextInput:
id: new_post_input
.
.
.
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selected_text)
I'm trying to create a screen which has a horizontal scrollview at the top of the page, taking up ~25% of the vertical space and a vertical scrollview taking up the rest of the space (and then being able to scroll further down the screen).
I've managed to create a horizontal scrollview but can't get the vertical scrollview to work on the same screen.
py file:
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.image import Image
from
Window.clearcolor = (1,1,1,1)
class Window(Screen):
pass
class MyApp(App):
theme_cls = ThemeManager()
def build(self):
kv = Builder.load_file("kivy.kv")
self.sm = WindowManager()
screens = [Window(name="window")]
for screen in screens:
self.sm.add_widget(screen)
self.sm.current = "window"
return self.sm
if __name__ == '__main__':
MyApp().run()
kv file:
<Window>:
name: "window"
NavigationLayout:
id: nav_layout
MyNavDrawer:
BoxLayout:
orientation: "vertical"
MDToolbar:
pos_hint: {'top': 1}
md_bg_color: 1, 1, 1, 1
ScrollView: #horizontal scrollview - works fine
size_hint_y: 0.5
GridLayout:
rows: 1
id: scroll_horizontal
size_hint_x: None
col_default_width: root.width*0.2
width: self.minimum_width*1.3
spacing: 20
ScrollView: #vertical scrollview, not working
size_hint_y: 0.85
do_scroll_x: False
GridLayout:
id: scroll_vertical
cols: 1
size_hint_y: None
spacing: 40
height: self.minimum_height
canvas:
Color:
rgba: (1, 1, 1, 1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
cols: 2
spacing: 10
Button:
size_hint_y: 0.5
text: "Btn1"
Button:
size_hint_y: 0.5
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
Button:
size_hint_y: 0.5
text: "Btn1"
Button:
size_hint_y: 0.5
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
Button:
size_hint_y: 0.5
text: "Btn1"
Button:
size_hint_y: 0.5
text: "Btn2"
I'd like them to be independent of each other, so you can either scroll horizontal on the top scrollview or scroll veritcally through the buttons on the boxlayouts on the vertical scrollview
It took some work to get your MCVE working, but here is the part of your kv that I modified to get scrolling working in both directions with two ScrollViews:
ScrollView: #horizontal
size_hint_y: 0.25
do_scroll_y: False
GridLayout:
rows: 1
id: scroll_horizontal
size_hint: None, 1
col_default_width: root.width*0.2
width: self.minimum_width*1.3
spacing: 20
BoxLayout:
cols: 2
spacing: 10
size_hint_x: None
width: self.minimum_width
Button:
size_hint: None, 1
width: 500
text: "Btn1"
Button:
size_hint: None, 1
width: 500
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_x: None
width: self.minimum_width
Button:
size_hint: None, 1
width: 500
text: "Btn1"
Button:
size_hint: None, 1
width: 500
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_x: None
width: self.minimum_width
Button:
size_hint: None, 1
width: 500
text: "Btn1"
Button:
size_hint: None, 1
width: 500
text: "Btn2"
ScrollView: # vertical
size_hint_y: 0.75
do_scroll_x: False
GridLayout:
id: scroll_vertical
cols: 1
size_hint: 1.0, None
spacing: 40
# must set height
height: self.minimum_height
BoxLayout:
cols: 2
spacing: 10
size_hint_y: None
Button:
size_hint: 0.5, None
height: 100
text: "Btn1"
Button:
size_hint: 0.5, None
height: 100
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_y: None
height: self.minimum_height
Button:
size_hint: 0.5, None
height: 100
text: "Btn1"
Button:
size_hint: 0.5, None
height: 100
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_y: None
height: self.minimum_height
Button:
size_hint: 0.5, None
height: 100
text: "Btn1"
Button:
size_hint: 0.5, None
height: 100
text: "Btn2"
If you look under the first GridLayout there is an Image widget. I'm trying to get it to move to the right side of the screen. Any help is appropriated. Here's the code. The id of the widget I need on the right hand side is id=image. I can't seem to move it at all.
I'm giving more details because stackoverflow want's it. I think the above is pretty detailed really stackoverflow, but your in charge so here is more text.
Thank you everyone.
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
Builder.load_string("""
<ClientScreen>:
GridLayout:
id: main_grid_layout
orientation: 'vertical'
cols: 1
Label:
id: name_label
text: '<NO MENU NAME>'
size_hint_y: None
size: self.texture_size
halign: 'left'
valign: 'center'
text_size: self.size
padding_x: 35
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Image:
id: image
pos_hint: {'right': 0.5}
ScrollView:
id: text_scroll_view
bar_width: 10
size: self.size
GridLayout:
id: text_grid_layout
orientation: 'vertical'
cols: 1
size_hint_y: None
height: self.minimum_height
ScrollView:
size: self.size
bar_width: 10
size_hint_y: 0.40
GridLayout:
id: action_grid_layout
# padding: [10, 10, 10, 10]
orientation: 'vertical'
cols: 1
size_hint_y: None
# row_default_height: 30
height: self.minimum_height
""")
class LoginScreen(Screen):
pass
class ClientScreen(Screen):
pass
class MyApp(App):
def build(self):
from kivy.core.window import Window
sm = ScreenManager()
sm.transition = NoTransition()
global CLIENT_SCREEN
LOGIN_SCREEN = LoginScreen(name='login')
CLIENT_SCREEN = ClientScreen(name='client')
sm.add_widget(LOGIN_SCREEN)
sm.add_widget(CLIENT_SCREEN)
sm.current = 'client'
Window.size = (300, 120)
self.title = 'xNemesis Client V0'
return sm
MyApp().run()
In the kv file, do the following. Please refer to the example below for details.
Replace GridLayout: with BoxLayout: because GridLayout with cols: 1 has the similar presentation as BoxLayout with orientation: 'vertical'.
Remove cols: 1
At Image:, add size_hint_x: 0.4
Replace pos_hint: {'right': 0.5} with pos_hint: {'right': 1}
Note
GridLayout does not has an attribute called orientation.
Example
main.py
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
Builder.load_string("""
<ClientScreen>:
BoxLayout:
id: main_grid_layout
orientation: 'vertical'
Label:
id: name_label
text: '<NO MENU NAME>'
size_hint_y: None
size: self.texture_size
halign: 'left'
valign: 'center'
text_size: self.size
padding_x: 35
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Image:
id: image
source: 'raspberrypi.png'
size_hint_x: 0.4
pos_hint: {'right': 1}
ScrollView:
id: text_scroll_view
bar_width: 10
size: self.size
GridLayout:
id: text_grid_layout
orientation: 'vertical'
cols: 1
size_hint_y: None
height: self.minimum_height
ScrollView:
size: self.size
bar_width: 10
size_hint_y: 0.40
GridLayout:
id: action_grid_layout
# padding: [10, 10, 10, 10]
orientation: 'vertical'
cols: 1
size_hint_y: None
# row_default_height: 30
height: self.minimum_height
""")
class LoginScreen(Screen):
pass
class ClientScreen(Screen):
pass
class MyApp(App):
def build(self):
from kivy.core.window import Window
sm = ScreenManager()
sm.transition = NoTransition()
global CLIENT_SCREEN
LOGIN_SCREEN = LoginScreen(name='login')
CLIENT_SCREEN = ClientScreen(name='client')
sm.add_widget(LOGIN_SCREEN)
sm.add_widget(CLIENT_SCREEN)
sm.current = 'client'
Window.size = (300, 120)
self.title = 'xNemesis Client V0'
return sm
MyApp().run()
Output
When i pass blank value in array
arr = ({'Item1': ''},{'Item2': 1000})
then it show 0 instead of blank value.
1. Can someone tell me how to set blank by deafault instead of 0 ?
2. How to make key(Item1) bold?
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
def convert_data(data):
l = []
for item in data:
for key, value in item.items():
l.append({'text': key, 'value': value})
return l
class Invoice(Screen):
def abc(self):
#fetching from database
arr = ({'Item1': ''},{'Item2': 1000})
# convert to [{'text': 'Item1', 'value': 5000}, {'text': 'Item2', 'value': 1000}]
self.rv.data = convert_data(arr)
class MyApp(App):
def build(self):
return Builder.load_file('test.kv')
if __name__ == '__main__':
MyApp().run()
test.kv
<Button#Button>:
font_size: 15
size_hint_y:None
height: 30
<Label#Label>:
font_size: 15
size_hint_y:None
height: 30
<Item#GridLayout>:
cols: 2
text: ""
value: 0
padding : 5, 0
spacing: 10, 0
Label:
size_hint_x: .35
text: root.text
halign: 'left'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Label:
size_hint_x: .15
text: str(root.value)
halign: 'right'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Invoice:
rv: rv
BoxLayout:
orientation: "vertical"
padding : 15, 15
BoxLayout:
orientation: "vertical"
padding : 5, 5
size_hint: .6, None
pos_hint: {'x': .18,}
BoxLayout:
orientation: "horizontal"
padding : 5, 5
spacing: 10, 10
size: 800, 40
size_hint: 1, None
Button:
text: "Show"
size_hint_x: .05
spacing_x: 30
on_press:root.abc()
BoxLayout:
orientation: "horizontal"
size_hint: 1, 1
BoxLayout:
orientation: "vertical"
size_hint: .5, 1
padding : 0, 15
spacing: 10, 10
size: 500, 30
Button:
text: "Invoice"
text_size: self.size
halign: 'center'
valign: 'middle'
BoxLayout:
RecycleView:
id: rv
viewclass: 'Item'
RecycleBoxLayout:
default_size: None, dp(30)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
When I proposed this code in a previous question I assumed that the second fields were always going to be integers and not string, so create the value: 0 property which, as seen, accepts only numerical values since it is mapped as NumericProperty. The solution is to convert it to StringProperty by changing to value:"" besides changing the line of convert_data so that it does the conversion of integers to string.
In the second case to be able to use bold in the text we must set markup to True in Label and use [b] [/b] before and after the text that we want to modify.
All of the above implies the following changes:
*.py
[...]
def convert_data(data):
l = []
for item in data:
for key, value in item.items():
l.append({'text': key, 'value': str(value)}) # change this line
return l
[...]
*.kv
[...]
<Item#GridLayout>:
cols: 2
text: ""
value: ""
padding : 5, 0
spacing: 10, 0
Label:
size_hint_x: .35
text: "[b]{}[/b]".format(root.text)
markup: True
halign: 'left'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Label:
size_hint_x: .15
text: root.value
halign: 'right'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
[...]