Valign not working in kivy? - python

I have this kivy file here:
<Help>:
Label:
text: "[b]Help Page[/b]\n"
font_size: 30
markup: True
valign: "top"
color: 0,0,0,1
Label:
text: "[b] How To Use:[/b]\n"
font_size: 30
markup: True
valign: 'top'
color: 0,0,0,1
However, the text does not go to the top of the page. This is the output:
What is wrong with this? and may I also ask about how to format those overlapping text. Thanks :)
edit:
This is what I want to happen with the text:
desired output
So to get that result I tried using the valign and halign to format the text but it does not seem to work. Hope this clarified my question :)

Display Text at Top
To display the text at top using valign: 'top', replace text_size: root.width, None with text_size: root.width, root.height
Snippet
<Help>:
Label:
id: help
text_size: root.width, root.height
markup: True
valign: 'top'
halign: 'center'
color: 0,0,0,1
Output
Display Both Strings as One
To display both strings, "How to Operate: Some text here" and "Some title Some more text" as one, we will do the following:
kv file
<Help>:
Label:
id: help
text_size: root.width, None
markup: True
halign: 'center'
color: 0,0,0,1
Python Code
class Help(Screen):
def on_pre_enter(self, *args):
self.ids.help.text = "[size=30][b]How to Operate[/b][/size]\nSome text here" + \
"\n\n[size=30][b]Some title[/b][/size]\nSome more text"
Output - Combined Text
Text Overlapping
The Label's text are overlapping because you are adding two Label widgets on-top each other in a Screen Layout.
Add a BoxLayout as parent of the two Label widgets to prevent text overlapping.
Text Wrapping
Wraps the text at a certain width, provide the width. For example, a Label to be created in a box with width=200 and unlimited height.
Label(text='Very big big line', text_size=(200, None))
Snippet
<Help>:
BoxLayout:
orientation: 'vertical'
Label:
text_size: dp(230), None
height: self.texture_size[1]
text: "[size=30][b]How to Operate[/b][/size]Some text here"
markup: True
valign: "top"
halign: 'center'
color: 0,0,0,1
Label:
text_size: dp(150), None
text: "[size=30][b]Some title[/b][/size]Some more text"
markup: True
valign: 'top'
halign: 'center'
color: 0,0,0,1
Output
Text Alignment
Add text_size: self.size
Snippet
<Help>:
Label:
text_size: self.size
text: "[b]Help Page[/b]\n"
font_size: 30
markup: True
valign: "top"
color: 0,0,0,1
Label:
text_size: self.size
text: "[b] How To Use:[/b]\n"
font_size: 30
markup: True
valign: 'top'
color: 0,0,0,1
Text alignment and wrapping
In order for the halign and valign alignment properties to
take effect, set the text_size, which specifies the size of the
bounding box within which text is aligned.
Output

Related

How to reference other class methods in kivy

I'm new to stack overflow but I've been programming in python for a couple years. One thing I havent done much of is object oriented programming. I just started learning kivy and I think I might have screwed up the root of my program by organizing it wrong. I used classes to define each label, button, layout...etc. now I'm wondering how I can reference the attributes of each text input to use what's filled in for other methods I want to define.
Example: have a button when pressed gets the input from two different text inputs and adds them together and a label displays it.
You can see what I've tried in my code but I'm having a hell of a time figuring out how to reference all these things from different classes.
I hope my code is understandable...sorry its lengthy but I want you to see the whole scope of what I did. I'm really hoping I can get a solution to where I can keep my organization and have certain things only show up under their own files but I understand if I have to change a lot of things...
Main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.gridlayout import GridLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from os import listdir
from kivy.core.window import Window
#load all files with 'kv' in folder
kv_path = './kv/'
for kv in listdir(kv_path):
Builder.load_file(kv_path+kv)
#move the keyboard below text input
Window.softinput_mode = 'below_target'
#classes for savings and loan screens
class SaveButton(Button):
pass
class LoanButton(Button):
pass
class Calculate(Button):
def add(self):
total = SaveDepositInput.inideposit +GoalAmountInput.amount
return total
pass
class TotalsLabel(Label):
pass
#layout classes
class MainBoxLayout(BoxLayout):
pass
class InsideAnchorLayout(AnchorLayout):
pass
class OneColGridlayout(GridLayout):
pass
class AColGridLayout(GridLayout):
pass
class TwoColGridLayout(GridLayout):
pass
class WidgetRelativeLayout(RelativeLayout):
pass
#Toggle Buttons
class DailyToggle(ToggleButton):
pass
class WeeklyToggle(ToggleButton):
pass
class BiWeeklyToggle(ToggleButton):
pass
class MonthlyToggle(ToggleButton):
pass
class YearlyToggle(ToggleButton):
pass
class NoneToggle(ToggleButton):
pass
class Monthly2Toggle(ToggleButton):
pass
class Yearly2Toggle(ToggleButton):
pass
#classes for screen change
class SaveScreen(Screen):
pass
class LoanScreen(Screen):
pass
class SaveLoanTabs(TabbedPanel):
pass
#classes for savings screen
class OutputLabel(Label):
pass
class GoalOutputLabel(Label):
pass
class NoReinvestLabel(Label):
pass
class SaveInstructLabel(Label):
pass
class SaveDepositLabel(Label):
pass
class SaveDepositInput(TextInput):
def inideposit(self):
initial = root.TextInput.text
deposit = int(initial)
return deposit
pass
class SaveYearsLabel(Label):
pass
class SaveYearsInput(TextInput):
pass
class SaveMonthsInput(TextInput):
pass
class ChooseCompoundLabel(Label):
pass
class SaveInterestLabel(Label):
pass
class SaveInterestInput(TextInput):
pass
class RepeatDepositLabel(Label):
pass
class RepeatDeposit2Label(Label):
pass
class RepeatDepositInput(TextInput):
pass
class YearsLabel(Label):
pass
class MonthsLabel(Label):
pass
class GoalAmount(Label):
pass
class GoalAmountInput(TextInput):
def amount(self):
initial = root.TextInput.text
goal = int(initial)
return goal
pass
#classes for loan screen
class LoanOutputLabel(Label):
pass
class LoanInstructLabel(Label):
pass
class LoanAmountLabel(Label):
pass
class LoanAmountInput(TextInput):
pass
# Create the screen manager
sm = ScreenManager()
sm.add_widget(SaveScreen(name='save'))
sm.add_widget(LoanScreen(name='loan'))
#class to run app
class InterestApp(App):
def build(self):
self.title = "Compound Interest and Loan Application"
return sm
#run app
if __name__ == "__main__":
InterestApp().run()
Main.kv file(mostly used for layout formatting)
<SaveScreen>:
MainBoxLayout:
GridLayout:
cols: 2
SaveButton:
on_press: root.manager.current = 'save'
LoanButton:
on_press: root.manager.current = 'loan'
InsideAnchorLayout:
GridLayout:
cols: 1
canvas:
Color:
rgba: .7,1,.7,1
Rectangle:
size: self.size
pos: self.pos
SaveInstructLabel:
InsideAnchorLayout:
TwoColGridLayout:
SaveDepositLabel:
SaveDepositInput:
InsideAnchorLayout:
AColGridLayout:
ChooseCompoundLabel:
InsideAnchorLayout:
AColGridLayout:
cols: 3
DailyToggle:
MonthlyToggle:
YearlyToggle:
InsideAnchorLayout:
TwoColGridLayout:
SaveInterestLabel:
SaveInterestInput:
InsideAnchorLayout:
AColGridLayout:
RepeatDepositLabel:
InsideAnchorLayout:
AColGridLayout:
cols: 5
NoneToggle:
WeeklyToggle:
BiWeeklyToggle:
Monthly2Toggle:
Yearly2Toggle:
InsideAnchorLayout:
TwoColGridLayout:
RepeatDeposit2Label:
RepeatDepositInput:
InsideAnchorLayout:
TwoColGridLayout:
size_hint_y: None
height: dp(50)
SaveYearsLabel:
TwoColGridLayout:
YearsLabel:
SaveYearsInput:
MonthsLabel:
SaveMonthsInput:
InsideAnchorLayout:
TwoColGridLayout:
GoalAmount:
GoalAmountInput:
InsideAnchorLayout:
GridLayout:
cols: 1
canvas:
Color:
rgba: .5,1,1,1
Rectangle:
size: self.size
pos: self.pos
size_hint: None, None
height: dp(80)
width: self.parent.width - dp(15)
TotalsLabel:
OutputLabel:
GoalOutputLabel:
NoReinvestLabel:
InsideAnchorLayout:
AColGridLayout:
Calculate:
<LoanScreen>:
MainBoxLayout:
TwoColGridLayout:
SaveButton:
on_press: root.manager.current = 'save'
LoanButton:
on_press: root.manager.current = 'loan'
Buttons.kv
<SaveButton>:
id: 'save'
text: "[u]Save[/u]"
color: 1, .9, 0, 1
background_normal: ''
background_color: (.5, .5, .5, 1) if self.state == 'normal' else (0, .75, 1, 1)
group: 'menu'
markup: True
<LoanButton>:
text: "[u]Loan[/u]"
markup: True
color: 1, .9, 0, 1
background_normal: ''
background_color: (.5, .5, .5, 1) if self.state == 'normal' else (0, .75, 1, 1)
group: 'menu'
<DailyToggle>:
text: 'Daily'
group: 'compound'
<MonthlyToggle>:
text: 'Monthly'
group: 'compound'
<YearlyToggle>:
text: 'Yearly'
group: 'compound'
<WeeklyToggle>:
text: 'Weekly'
group: 'repeat'
<Yearly2Toggle>:
text: 'Yearly'
group: 'repeat'
<Monthly2Toggle>:
text: 'Monthly'
group: 'repeat'
<BiWeeklyToggle>:
text: 'Bi-Weekly'
group: 'repeat'
<NoneToggle>:
text: 'None'
group: 'repeat'
<Calculate>:
text: '[u][b]Calculate[/b][/u]'
markup: True
on_release: self.add
Labels.kv
<SaveInstructLabel>:
text: "[b]This is the Savings screen. It will calculate compounded interest over a period of time and tell you the result. Follow each prompt to calculate.[/b]"
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
markup: True
<SaveDepositLabel>:
text: "Enter initial deposit amount:"
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<ChooseCompoundLabel>:
text: "Choose frequency of compounding interest:"
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<SaveInterestLabel>:
text: 'Enter the interest APY:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<RepeatDepositLabel>:
text: 'How often will you make a deposit:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<SaveYearsLabel>:
text: 'Enter the amount of years and months you will have this account build:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
font_size: dp(15)
<YearsLabel>:
text: 'Years:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'right'
color: 0,0,0,1
<MonthsLabel>:
text: 'Months:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'right'
color: 0,0,0,1
<GoalAmount>:
text: '(Optional)Enter an amount you would like to reach:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<OutputLabel>:
text: app.Calculate.add
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<GoalOutputLabel>:
text: 'total years to reach goal'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<NoReinvestLabel>:
text: 'if you didnt reinvest'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<TotalsLabel>:
text: '[u][b]TOTALS:[/b][/u]'
markup: True
valign: 'middle'
halign: 'center'
color: 0,0,0,1
<RepeatDeposit2Label>:
text: 'Enter recurring deposit amount:'
text_size: root.width, None
size: self.texture_size
valign: 'middle'
halign: 'center'
color: 0,0,0,1
Textboxes.kv
<SaveDepositInput>:
multiline: False
hint_text: '$0.00'
input_filter: 'float'
size_hint_y: None
height: dp(25)
<SaveInterestInput>:
multiline: False
hint_text: '0.0'
input_filter: 'float'
size_hint_y: None
height: dp(25)
<SaveYearsInput>:
multiline: False
hint_text: '0'
input_filter: 'int'
size_hint_y: None
height: dp(25)
<SaveMonthsInput>:
multiline: False
hint_text: '0'
input_filter: 'int'
size_hint_y: None
height: dp(25)
<GoalAmountInput>:
multiline: False
hint_text: '$0.00'
input_filter: 'float'
size_hint_y: None
height: dp(25)
<RepeatDepositInput>:
multiline: False
hint_text: '$0.00'
input_filter: 'float'
size_hint_y: None
height: dp(25)
And Layouts.kv
<MainBoxLayout>:
spacing: dp(2)
orientation: 'vertical'
canvas.before:
Color:
rgba: .7,1,.7,1
Rectangle:
size: self.size
pos: self.pos
<TwoColGridLayout>:
cols: 2
size_hint: .95, .70
canvas:
Color:
rgba: .5,1,1,1
Rectangle:
size: self.size
pos: self.pos
<OneColGridLayout>:
cols: 1
<AColGridLayout>:
cols: 1
size_hint: .95,.70
canvas:
Color:
rgba: .5,1,1,1
Rectangle:
size: self.size
pos: self.pos
<WidgetRelativeLayout>:
<InsideAnchorLayout>:
anchor_x: 'center'
In your Calculate Button, the add method is trying to call static methods, but the methods you name are actually instance methods. So you need to call them as instance methods. That means that you must have the instances of SaveDepositInput and GoalAmountInput. Since all of these things are in your SaveScreen, you can easily reference them using ids. To do this you cn add an id to SaveDepositInput in your SaveScreen:
InsideAnchorLayout:
TwoColGridLayout:
SaveDepositLabel:
SaveDepositInput:
id: save_deposit_input
and for the GoalInputAmount:
InsideAnchorLayout:
TwoColGridLayout:
GoalAmount:
GoalAmountInput:
id: goal_amount_input
then, in order to access these from the Calculate Button:
InsideAnchorLayout:
AColGridLayout:
Calculate:
gai: goal_amount_input
sdi: save_deposit_input
Then, the CalculateButton class becomes:
class Calculate(Button):
def add(self):
total = self.sdi.inideposit() + self.gai.amount()
return total
A couple other issues. The CalculateButton in your Buttons.kv should be:
<Calculate>:
text: '[u][b]Calculate[/b][/u]'
markup: True
on_release: self.add()
( you were missing the ())
And you have a similar class vs instance issue with your OutputLabel in your Labels.kv.

Handling keyboard input in regard to its source in Kivy

I am currently experimenting a bit with Kivy and added a TextInput to my GUI.
I now want to keep features such as deleting the last character when pressing backspace and so on but also want Kivy to execute a method when a new letter is entered to my textInput.
How would I do that? I tried the following code which works in terms of calling said function but doesn't keep the backspace and delete functionality.
Code:
KV
#:kivy 1.9.0
<PageLayout>:
GridLayout:
searchterm: searchterm
cols: 2
rows: 2
spacing: 5
padding: 5
Button:
text: "maybe a listview of latest traces here"
size_hint: .2,.5
BoxLayout:
orientation:'vertical'
TextInput:
id: searchterm
multiLine: False
hint_text: "Search for specific processes here"
keyboard_on_key_down: root.on_search
Button:
text: "room for imagination"
size_hint: 0.2, .5
Button:
text: "out of ideas"
BoxLayout:
orientation: "vertical"
Button:
text: "this is a new page for additional information"
Label:
halign: 'center'
valign: 'center'
size_hint: None, .025
width: self.parent.width
text: "About:"
color: 0,0,0,1 #textcolor
canvas.before:
Color:
rgba: 0.5,0.5,0.5,1
Rectangle:
pos: self.pos
size: self.size
Label:
halign: 'center'
valign: 'center'
size_hint: None, .025
width: self.parent.width
text: "This tool was written by me"
color: 0,0,0,1 #textcolor
canvas.before:
Color:
rgba: 0.5,0.5,0.5,1
Rectangle:
pos: self.pos
size: self.size
Label:
halign: 'center'
valign: 'center'
size_hint: None, .025
width: self.parent.width
text: "It is only meant for evaluation and testing purposes."
color: 0,0,0,1 #textcolor
canvas.before:
Color:
rgba: 0.5,0.5,0.5,1
Rectangle:
pos: self.pos
size: self.size
Python
import kivy
from kivy.app import App
from kivy.uix.pagelayout import PageLayout
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.widget import Widget
#WINDOW ATTRIBUTES
Config.set('graphics','resizable','1')
Config.set('graphics','width','1000')
Config.set('graphics','height','800')
class Visualizer(PageLayout):
searchterm = ObjectProperty(None)
def on_search(self,*args,**kwargs):
print("Test")
print(*args)
print(**kwargs)
class VisualizerApp(App):
def build(self):
self.title = "MQTT IDS Visualizer. Author: Daniel"
return Visualizer()
GLAPP = VisualizerApp()
GLAPP.run()
You need to call the super for keyboard_on_key_down. I believe the easiest way to do that is to define a subclass of TextInput like so:
class MyTextInput(TextInput):
def keyboard_on_key_down(self, window, keycode, text, modifiers):
App.get_running_app().root.on_search( window, keycode, text, modifiers) # calls your `on_search()` method
return super(MyTextInput, self).keyboard_on_key_down(window, keycode, text, modifiers)
Then replace TextInput with MyTextInput in your kv file.

Multiple valigns in one label

I am programming a Chat Bot and I want to build a GUI using kivy. To make the chat I am using labels in a scrollview:
GridLayout:
cols: 1
rows: 0
ScrollView:
size: self.size
do_scroll_x: False
Label:
id: msg
text_size: self.width,None
size_hint_y: None
height: self.texture_size[1]
font_size: 20
Python Code:
def send(self,x):
#global msgback
self.msg_list.text += str(x + "\n")
The problem is, that I do not know how to make the valign, that only makes the messages from the user on the right side. How do I do that?
Use halign to align text to the right.
Label:
id: msg
text_size: self.width,None
size_hint_y: None
height: self.texture_size[1]
font_size: 20
halign: 'right'
valign: 'middle'
Label » halign
halign
Horizontal alignment of the text.
halign is an OptionProperty and defaults to ‘left’. Available options
are : left, center, right and justify.
Warning
This doesn’t change the position of the text texture of the Label
(centered), only the position of the text in this texture. You
probably want to bind the size of the Label to the texture_size or set
a text_size.

Kivy (kv language) StackLayout Issue and Boundary Issue

I'm new to Kivy and still working out the best way to use it. Currently, I'm taking an example from their repo (textsize demo) and attempting to use layout concepts in a personal project.
At the end of the day, all I want is a "navbar" at the top of my screen and a content section below it. At the moment, I'm trying to accomplish this with a BoxLayout which includes a StackLayout (nav items) and a GridLayout (other content).
My Code Snippet:
<WindowWidget>:
BoxLayout:
orientation: 'vertical'
StackLayout:
Label:
text: 'Test1'
Label:
text: 'Test1.1'
Label:
text: 'Test2'
This code produces this: Kivy Screenshot.
I don't understand why label 1.1 is pushed down on top of label 2 rather than appearing beside label 1.
I added the following code taken from the kivy examples hoping the height setting would add some clarity, but I get the error below:
Code:
<StackLayout>:
size_hint_y: None
spacing: dp(6)
padding: dp(6), dp(4)
height: self.minimum_height
Error:
Warning, too much iteration done before the next frame. Check your
code, or increase the Clock.max_iteration attribute
This is caused by my inclusion of the "height: self.minimum_height" line. However, this works in the demo, so I'm not sure how I managed to screw it up. I'll include the example's kv code below for reference.
The original:
BoxLayout:
orientation: 'vertical'
HeadingLabel:
text: 'These modify all demonstration Labels'
StackLayout:
# Button is a subclass of Label and can be sized to text in the same way
Button:
text: 'Reset'
on_press: app.reset_words()
ToggleButton:
text: 'Shorten'
on_state:
app.shorten=self.state=='down'
ToggleButton:
text: 'max_lines=3'
on_state:
app.max_lines=3 if self.state=='down' else 0
Spinner:
text: 'bottom'
values: 'bottom', 'middle', 'top'
on_text: app.valign=self.text
Spinner:
text: 'left'
values: 'left', 'center', 'right', 'justify'
on_text: app.halign=self.text
GridLayout:
id: grid_layout
cols: 2
height: cm(6)
size_hint_y: None
HeadingLabel:
text: "Default, no text_size set"
HeadingLabel:
text: 'text_size bound to size'
DemoLabel:
id: left_content
disabled_color: 0, 0, 0, 0
DemoLabel:
id: right_content
text_size: self.size
padding: dp(6), dp(6)
ToggleButton:
text: 'Disable left'
on_state:
left_content.disabled=self.state=='down'
# Need one Widget without size_hint_y: None, so that BoxLayout fills
# available space.
HeadingLabel:
text: 'text_size width set, size bound to texture_size'
text_size: self.size
size_hint_y: 1
DemoLabel:
id: bottom_content
# This Label wraps and expands its height to fit the text because
# only text_size width is set and the Label size binds to texture_size.
text_size: self.width, None
size: self.texture_size
padding: mm(4), mm(4)
size_hint_y: None
# The column heading labels have their width set by the parent,
# but determine their height from the text.
<HeadingLabel#Label>:
bold: True
padding: dp(6), dp(4)
valign: 'bottom'
height: self.texture_size[1]
text_size: self.width, None
size_hint_y: None
<ToggleButton,Button>:
padding: dp(10), dp(8)
size_hint: None, None
size: self.texture_size
# This inherits Button and the modifications above, so reset size
<Spinner>:
size: sp(68), self.texture_size[1]
<DemoLabel#Label>:
halign: app.halign
valign: app.valign
shorten: app.shorten
max_lines: app.max_lines
canvas:
Color:
rgb: 68/255.0, 164/255.0, 201/255.0
Line:
rectangle: self.x, self.y, self.width, self.height
<StackLayout>:
size_hint_y: None
spacing: dp(6)
padding: dp(6), dp(4)
height: self.minimum_height
TYIA

Change custom buttons attributes

I created a custom button as follows
#: import icon kivy.garden.iconfonts.icon
<custom_Button#Button>:
background_normal: 'icons/backg.png'
RelativeLayout:
size: self.parent.width, self.parent.height
top: self.parent.top
right: self.parent.right
Label:
canvas.before:
Color:
rgba: 1,1,1,1
Rectangle:
pos: self.pos
size: self.size
source: 'icons/restaurant.png'
color: 0,0,0,1
id: icon_name
markup: True
font_size: '20dp'
text: '{}'.format(icon('ion-settings', 38))
pos_hint: {'center_y': .5, 'right': .25}
size_hint: .18, .9
Label:
text:'Change Settings'
id: label
color: 0,0,0,1
text_size: self.size
halign: 'left'
valign: 'middle'
font_size: '20dp'
pos_hint: {'center_y': .5, 'right': 1}
size_hint: .7, .9
i want to be able to pass this (Custom_Button) as a child to different layouts, and change some of the attributes to what i want. Heres what i mean.
for example,
GridLayout:
custom_Button
custom_Button
custom_Button
But i would like to be able to explicitly change the label icon for the first label in the custom_Button, also the text in the second Label, so that for the three instances of the cutom_Button a different icon and text would be displayed. I really dont know how to achieve this. So please i need some help.
An example code will be very helpful. Thanks in advance...
First of all, do change the class name to something standard, like CustomButton. Then, define a new property containing the icon_source:
<CustomButton#Button>:
icon_source: 'icons/restaurant.png'
...
and refer to it later:
Rectangle:
pos: self.pos
size: self.size
source: root.icon_source
Then it's simple to change this for every instance, either in kv or in python:
GridLayout:
CustomButton:
icon_source: 'something/else.png'

Categories