Related
I am making an app using kivy & kivymd and in one part of it, I would like the labels to take as much space as the actual text.
This seems pretty straightforward with kivy itself but for some reason, nothing works with the MDLabel class. I tried setting the adaptive_width property to True and I also tried to directly set the width to the texture_size[0] property but none of them worked (and yes I installed kivymd directly from github).
Here is my code:
from kivy.lang import Builder
from kivymd.app import MDApp
class MainApp(MDApp):
def __init__(self, **kwargs):
super(MainApp, self).__init__(**kwargs)
self.kv = Builder.load_string('''
#:kivy 2.0.0
BoxLayout:
MDLabel:
text: "Supposedly adaptive width (KivyMD)"
font_size: "21sp"
halign: "center"
adaptive_width: True
# I also tried directly setting the width to the texture_size but the results were worse
# size_hint_x: None
# width: self.texture_size[0]
canvas.before:
Color:
rgba: .8, .1, .2, .5
Rectangle:
pos: self.pos
size: self.size
Widget:
MDSeparator:
orientation: "vertical"
Widget:
Label:
text: "Actual adaptive width (Standard Kivy)"
font_size: "21sp"
color: 0, 0, 0, 1
size_hint_x: None
width: self.texture_size[0]
canvas.before:
Color:
rgba: 0, .6, .2, .5
Rectangle:
pos: self.pos
size: self.size
''')
def build(self):
return self.kv
if __name__ == '__main__':
MainApp().run()
Here is my results:
I don't believe that MDLabel supports the adaptive_width property. In using the width: self.texture_size[0], it seems that you must also add the text_size: None, None to the MDLabel, and it seems that its location in the kv is important. Here is a version of part of your kv that seems to work:
BoxLayout:
MDLabel:
text: "Supposedly adaptive width (KivyMD)"
font_size: "21sp"
halign: "center"
# adaptive_width: True
# I also tried directly setting the width to the texture_size but the results were worse
size_hint_x: None
width: self.texture_size[0]
text_size: None, None # added, and must be in this location
canvas.before:
Color:
rgba: .8, .1, .2, .5
Rectangle:
pos: self.pos
size: self.size
How can I dynamically add a button to a particular screen of my .kv file's screenmanager? The problem is, the buttons that get created show up on all screens.
I have a program I am working on that will allow the user to input there particular conditions and calculate ACFM. I am currently trying to set up a file screen that allows the user to create multiple files. I am trying to allow one main button called "create new file" creates more buttons on the first screen. The problem is, the buttons that get created show up on all screens.
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
import Functions as f1
from kivy.uix.button import Button
Window.size = (300,625)
window_x = Window.width
window_y = Window.height
Builder.load_file("main.kv")
class counter:
def __init__(self):
self.count = 2
def increase(self):
self.count += 1
b = counter()
class Calc(FloatLayout):
def testbutton(self,instance):
btn = Button(text = "testing123", color = (1,1,1,1),
size_hint =(.5,.05),
pos = (0,(window_y-(window_y*(.07+(b.count*.05)))))
)
b.increase()
self.add_widget(btn)
# define the multiplication of a function
def calculate(self, instance):
f = float(self.flow.text)
p = float(self.pressure.text)
t = float(self.temperature.text)
sg = float(self.specific_gravity.text)
self.acfm.text = str(f) #str(f1.ACFM(f,p,t,sg)) I commented this out for the purpose of posting this in my questions.
class test(App):
def build(self):
return Calc()
if __name__=="__main__":
test().run()
main.kv
<calc>:
flow: _flow
pressure: _pressure
temperature: _temperature
specific_gravity: _specific_gravity
acfm: _acfm
FloatLayout:
ScreenManager:
id: screen_manager
size: self.size
Screen:
name: "filescreen"
FloatLayout:
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: self.width, self.height
pos: self.pos
AnchorLayout:
anchor_x: 'center'
anchor_y: 'top'
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.size
pos: self.pos
Color:
rgb: 0,0,0
Line:
width: 1
rectangle: self.x,self.y,self.width,self.height
size_hint: 1,.07
FilescreenButton:
text: "Create New File"
pos: 0,root.height-(root.height*(.07+.05))
on_press: root.testbutton(*args)
Screen:
name: "solverscreen"
GridLayout:
cols:1
size_hint: 1,1
ScrollView:
FloatLayout:
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: self.width, self.height
pos: self.pos
size_hint: 1,1.5
GridLayout:
cols:1
spacing: 1
pos_hint: {"top": (1),"left": 1}
size_hint: .4, None
row_default_height: root.height*.05
Label:
text: "Inputs"
color: 0,0,0,1
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
CustomLabel:
text: "Flow"
CustomLabel:
text: "Pressure"
CustomLabel:
text: "Temperature"
CustomLabel:
text: "Specific Gravity"
Label:
text: "Results"
color: 0,0,0,1
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
Button:
text: "Calculate"
on_press: root.calculate(*args)
GridLayout:
cols:1
spacing: 1
pos_hint: {"top": (1),"right": .7}
size_hint: .3, None
row_default_height: root.height*.05
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
TextInput:
text: "0"
id: _flow
TextInput:
text: "0"
id: _pressure
TextInput:
text: "0"
id: _temperature
TextInput:
text: ".6"
id: _specific_gravity
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
Label:
id: _acfm
color: 0,0,0,1
canvas.before:
Color:
rgba: .7,.7,.7,1
Rectangle:
pos: self.pos
size: self.size
Color:
rgb: 1,1,1
Line:
width: 1
rectangle: self.x,self.y,self.width,self.height
GridLayout:
cols:1
spacing: 1
pos_hint: {"top": (1),"right": 1}
size_hint: .3, None
row_default_height: root.height*.05
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height/2
pos: self.pos
CustomButton:
text: "MMSCFD"
CustomButton:
text: "PSIG"
CustomButton:
text: "F"
CustomButton:
text: "SG"
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
CustomButton:
text: "ACFM"
AnchorLayout:
anchor_x: 'left'
anchor_y: 'bottom'
GridLayout:
cols: 4
size_hint: 1,.05
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: self.size
pos: self.pos
Button:
text: "Files"
on_press: screen_manager.current = 'filescreen'
Button:
text: "Solver"
on_press: screen_manager.current = 'solverscreen'
<CustomLabel#Label>:
#font_size: (((self.width*5)+(self.height))/6)*.12
canvas.before:
Color:
rgb: 0,0,0
Rectangle:
size: self.size
pos: self.pos
<CustomButton#Button>:
background_color: .25,.25,.25,1
canvas.before:
Color:
rgba: .25,.25,.25,1
Rectangle:
size: self.size
pos: self.pos
Line:
width: .09
rectangle: self.x,self.y,self.width,self.height
<FilescreenButton#Button>:
size_hint: .5,.05
color: 0,0,0,1
background_color: 1,1,1,0
canvas:
Color:
rgb: 0,0,0
Line:
width: 1
rectangle: self.x,self.y,self.width,self.height
I am not getting any error messages. I just want the dynamically created buttons from the .py file to only go to one screen of the .kv file.
You are currently adding it to the Calc FloatLayout which is the root and each screen is a child of this root. If you want to add it to just one screen, than you need to call the add_widgets function of that specific screen.
One option is via an id
change kv file like below
Screen:
id: id_solverscreen
name: "solverscreen"
change py file like below
self.ids.id_solverscreen.add_widget(btn)
python file
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
Window.size = (300,625)
window_x = Window.width
window_y = Window.height
Builder.load_file("main.kv")
class counter:
def __init__(self):
self.count = 2
def increase(self):
self.count += 1
b = counter()
class Calc(FloatLayout):
def testbutton(self,instance):
btn = Button(text = "testing123", color = (1,1,1,1),
size_hint =(.5,.05),
pos = (0,(window_y-(window_y*(.07+(b.count*.05)))))
)
b.increase()
self.ids.id_solverscreen.add_widget(btn)
# define the multiplication of a function
def calculate(self, instance):
f = float(self.flow.text)
p = float(self.pressure.text)
t = float(self.temperature.text)
sg = float(self.specific_gravity.text)
self.acfm.text = str(f) #str(f1.ACFM(f,p,t,sg)) I commented this out for the purpose of posting this in my questions.
class test(App):
def build(self):
return Calc()
if __name__=="__main__":
test().run()
kv file
<calc>:
flow: _flow
pressure: _pressure
temperature: _temperature
specific_gravity: _specific_gravity
acfm: _acfm
FloatLayout:
ScreenManager:
id: screen_manager
size: self.size
Screen:
name: "filescreen"
FloatLayout:
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: self.width, self.height
pos: self.pos
AnchorLayout:
anchor_x: 'center'
anchor_y: 'top'
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.size
pos: self.pos
Color:
rgb: 0,0,0
Line:
width: 1
rectangle: self.x,self.y,self.width,self.height
size_hint: 1,.07
FilescreenButton:
text: "Create New File"
pos: 0,root.height-(root.height*(.07+.05))
on_press: root.testbutton(*args)
Screen:
id: id_solverscreen
name: "solverscreen"
GridLayout:
cols:1
size_hint: 1,1
ScrollView:
FloatLayout:
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: self.width, self.height
pos: self.pos
size_hint: 1,1.5
GridLayout:
cols:1
spacing: 1
pos_hint: {"top": (1),"left": 1}
size_hint: .4, None
row_default_height: root.height*.05
Label:
text: "Inputs"
color: 0,0,0,1
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
CustomLabel:
text: "Flow"
CustomLabel:
text: "Pressure"
CustomLabel:
text: "Temperature"
CustomLabel:
text: "Specific Gravity"
Label:
text: "Results"
color: 0,0,0,1
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
Button:
text: "Calculate"
on_press: root.calculate(*args)
GridLayout:
cols:1
spacing: 1
pos_hint: {"top": (1),"right": .7}
size_hint: .3, None
row_default_height: root.height*.05
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
TextInput:
text: "0"
id: _flow
TextInput:
text: "0"
id: _pressure
TextInput:
text: "0"
id: _temperature
TextInput:
text: ".6"
id: _specific_gravity
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
Label:
id: _acfm
color: 0,0,0,1
canvas.before:
Color:
rgba: .7,.7,.7,1
Rectangle:
pos: self.pos
size: self.size
Color:
rgb: 1,1,1
Line:
width: 1
rectangle: self.x,self.y,self.width,self.height
GridLayout:
cols:1
spacing: 1
pos_hint: {"top": (1),"right": 1}
size_hint: .3, None
row_default_height: root.height*.05
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height/2
pos: self.pos
CustomButton:
text: "MMSCFD"
CustomButton:
text: "PSIG"
CustomButton:
text: "F"
CustomButton:
text: "SG"
Label:
canvas.before:
Color:
rgb: 1,1,1
Rectangle:
size: self.width,self.height
pos: self.pos
CustomButton:
text: "ACFM"
AnchorLayout:
anchor_x: 'left'
anchor_y: 'bottom'
GridLayout:
cols: 4
size_hint: 1,.05
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: self.size
pos: self.pos
Button:
text: "Files"
on_press: screen_manager.current = 'filescreen'
Button:
text: "Solver"
on_press: screen_manager.current = 'solverscreen'
<CustomLabel#Label>:
#font_size: (((self.width*5)+(self.height))/6)*.12
canvas.before:
Color:
rgb: 0,0,0
Rectangle:
size: self.size
pos: self.pos
<CustomButton#Button>:
background_color: .25,.25,.25,1
canvas.before:
Color:
rgba: .25,.25,.25,1
Rectangle:
size: self.size
pos: self.pos
Line:
width: .09
rectangle: self.x,self.y,self.width,self.height
<FilescreenButton#Button>:
size_hint: .5,.05
color: 0,0,0,1
background_color: 1,1,1,0
canvas:
Color:
rgb: 0,0,0
Line:
width: 1
rectangle: self.x,self.y,self.width,self.height
I try to make a simple ToDoList program.There are add, remove and do it buttons. But I have some bugs about labels color. When I click "DO IT" button label color change in scrollview but when I click remove button when some of them done, colored labels change. I did using canvas. How can I fix this problem?
class Home(Screen):
def __init__(self,**kwargs):
super(Home,self).__init__(**kwargs)
def addWidget(self):
task_input = self.ids.task_input.text
newListItem = EachTask(text=task_input ,
id=str((len(self.ids.add_field.children))) )
print(newListItem.id)
self.ids.add_field.add_widget(newListItem)
class EachTask(BoxLayout):
def __init__(self, text= "", **kwargs):
super(EachTask,self).__init__(**kwargs)
self.ids.label.text = text
def Do_Task(self,instance):
child = instance.parent.parent
with self.canvas.before:
Color(.5,1,.2,1, mode='rgba')
Rectangle(pos=child.ids.label.pos, size=child.ids.label.size)
kv_file
<FlatButton#ButtonBehavior+Label>:
font_size: 15
<Home>:
BoxLayout:
id: home
orientation: "vertical"
spacing: 5
#space_x: self.size[0]/2
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
##########HEADER#######
BoxLayout:
id: header
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: (.85,.7,.2,1)
Rectangle:
size: self.size
pos: self.pos
Label:
text: "TO DO LIST"
font_size: "20sp"
bold: True
size_hint_x: .9
FlatButton:
text: "Back"
size_hint_x: .1
####################################
ScrollView:
canvas.before:
Color:
rgba: (1,1,.2,.2)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
id: add_field
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
spacing: 2 #Spaces between childs
#####################################################
BoxLayout:
id: input_field
size_hint_y: None
height: 80
TextInput:
id: task_input
focus: True
size_hint_x: .9
multiline: False
Button:
font_size: "40sp"
size_hint_x: .1
text: "+"
on_release: root.addWidget()
id: button1
color: 1,0.5,0.5,1
#######################################################
<EachTask>:
size_hint_y: None
height: 50
id: each_task
BoxLayout:
Label:
size_hint_x: .8
id: label
canvas.before:
Color:
rgba: (1,.2,.2,.2)
Rectangle:
size: self.size
pos: self.pos
Button:
size_hint_x: .1
text: "X"
on_release: app.root.ids.add_field.remove_widget(root)
Button:
size_hint_x: .1
text: "DO IT"
on_release: root.Do_Task(self)
The following enhancements are required to the kv and py files to solve the problem.
Method 1 - Kivy automatically created & added an ObjectProperty, rgba
Kivy automatically created & added an ObjectProperty
If the widget doesn’t have a property with the given name, an
ObjectProperty will be automatically created and added to the widget.
kv file
Add a class attribute, rgba and initialize it to default colour, (1, .2, .2, .2) to class rule, <EachTask>:
Replace label's colour to root.rgba
Snippets - kv file
<EachTask>:
rgba: (1,.2,.2,.2) # Kivy auto created & added ObjectProperty, "rgba"
...
BoxLayout:
Label:
size_hint_x: .8
id: label
canvas.before:
Color:
rgba: root.rgba
...
py file
Remove all the codes in method Do_Task()
Add self.rgba = [.5, 1, .2, 1] whereby self refers to the current widget i.e. EachTask object.
Snippets - py file
def Do_Task(self, instance):
self.rgba = [.5, 1, .2, 1]
Method 2 - Explicitly declaring rgba
kv file
Replace rgba: (1,.2,.2,.2) with root.rgba
Snippets - kv file
<EachTask>:
...
BoxLayout:
Label:
size_hint_x: .8
id: label
canvas.before:
Color:
rgba: root.rgba
...
py file
Add import statement, from kivy.properties import ListProperty
Declare class attribute, rgba of ListProperty type and initilaize it to default colour, [1, .2, .2, .2] in class EachTask()
Remove all the codes in method Do_Task()
Add self.rgba = [.5, 1, .2, 1] whereby self refers to the current widget i.e. EachTask object.
Snippets - py file
from kivy.properties import ListProperty
...
class EachTask(BoxLayout):
rgba = ListProperty([1, .2, .2, .2])
...
def Do_Task(self, instance):
self.rgba = [.5, 1, .2, 1]
the two windows in the picture are exact copies(same line of code), only difference being that the right window is a screen inside a screen manager, but somehow the window on the right does not show the texts.
i'm not sure what the problem is and can't find anything related to it while doing research.
RIGHT WINDOW PYTHON FILE:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.config import Config
space = ""
x = [(a * 9), (a*16)]
Config.set('graphics', 'width', x[0])
Config.set('graphics', 'height', x[1])
class MainScreen(Screen):
pass
class SecondScreen(Screen):
pass
class ThirdScreen(Screen):
pass
kv = Builder.load_file("main2.kv")
class ComplimentUI(App):
def build(self):
return kv
def change_screen(self, x):
scrnmanager = self.root.ids['sm']
scrnmanager.current = x
if __name__ == "__main__":
ComplimentUI().run()
RIGHT WINDOW BUILDER FILE:(main2.kv)
#:include secondscreen.kv
#:include thirdscreen.kv
<MainScreen>:
canvas.before:
Color:
rgb: .59, .74, .20
Rectangle:
size: self.size
pos: self.pos
FloatLayout:
TextInput:
pos_hint: {'center_x':1, 'top':.1}
size_hint: .1,.1
multiline: False
font_size: 20
font_name: "Dimbo Regular"
background_normal: ''
background_color: 0,0,0,0
Button:
text: "PLAY!"
pos_hint: {'center_x':.5, 'center_y':.3}
size_hint: .8, .17
font_name: "Splatch"
color: 0.15, .5, 0.2, 1
font_size: 0.14 * self.width
background_normal: ''
background_color: 0,0,0,0
on_press:
print("pressed, navigating to prev screen")
app.change_screen("screentwo")
root.manager.transition.direction = "left"
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
ScreenManager:
GridLayout:
cols: 1
ScreenManager:
id: sm
MainScreen:
name: "screenone"
id: screenone
SecondScreen:
name: "screentwo"
id: screentwo
ThirdScreen:
name: "thirdscreen"
id: thirdscreen[enter image description here][1]
LEFT WINDOW PYTHON FILE:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config
space = "";
x = [(a * 9), (a*16)]
Config.set('graphics', 'width', x[0])
Config.set('graphics', 'height', x[1])
kv = Builder.load_file("main.kv")
class MyMainApp(App):
def build(self):
return kv
if __name__ == "__main__":
MyMainApp().run()
LEFT WINDOW BUILDER FILE:(main.kv)
FloatLayout:
canvas.before:
Color:
rgb: .59, .74, .20
Rectangle:
size: self.size
pos: self.pos
TextInput:
pos_hint: {'center_x':1, 'top':.1}
size_hint: .1,.1
multiline: False
font_size: 20
font_name: "Dimbo Regular"
background_normal: ''
background_color: 0,0,0,0
Button:
text: "PLAY!"
pos_hint: {'center_x':.5, 'center_y':.3}
size_hint: .8, .17
font_name: "Splatch"
color: 0.15, .5, 0.2, 1
font_size: 0.14 * self.width
background_normal: ''
background_color: 0,0,0,0
on_press:
print("pressed, navigating to prev screen")
app.change_screen("screentwo")
root.manager.transition.direction = "left"
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
NEW EDIT:
as i pointed out in the comment below, the same problem happens with the FloatLayout of secondscreen.kv and thirdscreen.kv, if i put it inside the builder file of the left window, its normal. But when i put it inside a screen inside a screen manager(like the right window) it's gone. the same problem happens to all my screens. the reason i only put the mainscreen.kv is because its the shortest out of all the screens, but nonetheless i will still provide the files, but only 1 version of it (the one used for the right window) since they're basically the same lines. (only difference being the added first line for its class name and a slight indetation change to fit the levels)
SECONDSCREEN BUILDER FILE:
<SecondScreen>:
FloatLayout:
canvas.before:
Color:
rgb: .59, .74, .20
Rectangle:
size: self.size
pos: self.pos
TextInput:
pos_hint: {'center_x':.5, 'center_y':.56}
size_hint: .8, .3
multiline: False
font_size: 20
font_name: "Dimbo Regular"
background_normal: ''
background_color: 1, 1, .8, 1
Label:
pos_hint: {'center_x':.5, 'center_y':.76}
size_hint: .8, .07
text: "NAME!"
font_size: 0.8 * self.height
font_name: "kidsrock"
color: 0.15, .5, 0.2, 1
background_color: 0,0,0,0
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
Button:
text: "<<<"
size_hint: .28, .07
pos_hint: {'center_x':.24, 'center_y':.1}
font_name: "kidsrock"
color: 0.15, .5, 0.2, 1
font_size: 0.35 * self.width
background_normal: ''
background_color: 0,0,0,0
on_press:
print("pressed, navigating to prev screen")
app.change_screen("screenone")
root.manager.transition.direction = "right"
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
Button:
pos_hint: {'center_x':.8, 'center_y':.35}
size_hint: .2, .07
background_normal: ''
background_color: 0,0,0,0
color: 0.15, .5, 0.2, 1
text: "ENTER"
font_name: "kidsrock"
font_size: 0.25 * self.width
on_press:
print("pressed, navigating to next screen")
app.change_screen("thirdscreen")
root.manager.transition.direction = "left"
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
THIRDSCREEN BUILDER FILE:
<ThirdScreen>:
FloatLayout:
canvas.before:
Color:
rgb: .59, .74, .20
Rectangle:
size: self.size
pos: self.pos
TextInput:
pos_hint: {'center_x':1, 'top':.1}
size_hint: .1, .1
multiline: False
font_size: 20
font_name: "Dimbo Regular"
background_normal: ''
background_color: 0, 0, 0, 0
Label:
pos_hint: {'center_x':.5, 'center_y':.71}
size_hint: .8, .17
text: "COMPLIMENT!"
font_size: 20
font_name: "kidsrock"
color: 0.15, .5, 0.2, 1
background_color: 0,0,0,0
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
Button:
pos_hint: {'center_x':.24, 'center_y':.1}
size_hint: .28, .07
font_name: "kidsrock"
color: 0.15, .5, 0.2, 1
font_size: 0.35 * self.width
text: "<<<"
background_normal: ''
background_color: 0,0,0,0
on_press:
print("pressed, navigating to prev screen")
app.change_screen("screentwo")
root.manager.transition.direction = "right"
canvas.before:
Color:
rgb: 1,1, .8,1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
NEW- NEW EDIT!:
UPDATE
after restarting my computer, it now looks like this.
Root Cause - Button & Label text not showing
The most probable cause is that the default color for text is white ([1, 1, 1, 1]), and the background color for both widgets are also white. You need to set the text color to non-white e.g. black ([0, 0, 0, 1]).
TextInput Box - not showing
The TexInput box is not visible in both windows (left & right) because of background_normal: '' and background_color: 0,0,0,0.
Comment them off and the TextInput box will be visible.
Button's text, 'PLAY' - not showing in right window
It could be something in the include kv files e.g. secondscreen.kv, and/or thirdscreen.kv that are/is causing the visibility. Comment off both kv files to trouble shoot the problem.
Example
The following example of the right window i.e. using ScreenManager is able to display the Button's text, "PLAY" and also the TextInput box.
main-right.py
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
class MainScreen(Screen):
pass
class SecondScreen(Screen):
pass
class ThirdScreen(Screen):
pass
kv = Builder.load_string("""
# :include secondscreen.kv
# :include thirdscreen.kv
<MainScreen>:
canvas.before:
Color:
rgb: .59, .74, .20
Rectangle:
size: self.size
pos: self.pos
FloatLayout:
TextInput:
hint_text: 'Type here'
pos_hint: {'center_x':1, 'top':.1}
size_hint: .1,.1
multiline: False
font_size: 20
# font_name: "Dimbo Regular"
# background_normal: ''
# background_color: 0,0,0,0
Button:
text: "PLAY!"
pos_hint: {'center_x':.5, 'center_y':.3}
size_hint: .8, .17
#font_name: "Splatch"
color: 0.15, .5, 0.2, 1
font_size: 0.14 * self.width
background_normal: ''
background_color: 0,0,0,0
on_press:
print("pressed, navigating to prev screen")
app.change_screen("screentwo")
root.manager.transition.direction = "left"
canvas.before:
Color:
rgba: 1, 1, .8, 1
RoundedRectangle:
size: self.size
pos: self.pos
radius: [4,]
GridLayout:
cols: 1
ScreenManager:
id: sm
MainScreen:
name: "screenone"
id: screenone
SecondScreen:
name: "screentwo"
id: screentwo
ThirdScreen:
name: "thirdscreen"
id: thirdscreen
""")
class RightWindow(App):
title = "ComplimentUI"
def build(self):
return kv
if __name__ == "__main__":
RightWindow().run()
Output
I was facing a similar problem and the bug for me turned out to be a declaration of size_hint_x for the button. Once I removed that, the text was visible.
I'm struggling for hours now, just to be able to customize the style of my TabbedPanel in Kivy. Here is my code:
#: import Utils kivy.utils
BoxLayout:
spacing: 0
padding: 0
canvas:
Color:
rgb: Utils.get_color_from_hex("#1b262d")[:3]
Rectangle:
size: self.size
TabbedPanel:
do_default_tab: False
tab_width: self.size[0] / 2
canvas:
Color:
rgb: Utils.get_color_from_hex("#00ff00")[:3]
Rectangle:
size: self.size
TabbedPanelItem:
background_color: Utils.get_color_from_hex("#1b262d")
text: "PAST"
background_down: ""
background_normal: ""
BoxLayout:
orientation: "vertical"
canvas:
Color:
rgb: Utils.get_color_from_hex("#1b262d")[:3]
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
padding: [10, 12, 10, 12]
spacing: 5
size_hint_y: 0.1
TextInput:
background_color: Utils.get_color_from_hex("#303E46")
foreground_color: [1, 1, 1, 1]
size_hint_x: 0.2
padding: [10, ( self.height - self.line_height ) / 2]
text: "DATES"
TextInput:
size_hint_x: 0.15
padding: [10, ( self.height - self.line_height ) / 2]
text: "TEST"
TextInput:
size_hint_x: 0.2
padding: [10, ( self.height - self.line_height ) / 2]
text: "CAT"
TextInput:
size_hint_x: 0.15
padding: [10, ( self.height - self.line_height ) / 2]
text: "SORT BY"
TextInput:
size_hint_x: 0.15
padding: [10, ( self.height - self.line_height ) / 2]
text: "SHOW ONLY"
TextInput:
size_hint_x: 0.15
padding: [10, ( self.height - self.line_height ) / 2]
text: "SEARCH"
BoxLayout:
size_hint_y: 0.8
spacing: 10
padding: 10
orientation: "horizontal"
canvas:
Color:
rgb: Utils.get_color_from_hex("#303E46")[:3]
Rectangle:
size: self.size
pos: self.pos
Button:
size_hint_x: 0.7
text: "TEST"
Button:
size_hint_x: 0.3
text: "TESTS"
TabbedPanelItem:
background_color: Utils.get_color_from_hex("#303E46")
text: "UPCOMING"
background_down: ""
background_normal: ""
here is the resulting window:
I actually highlighted in green the part I want to remove. I don't want this green part in the picture, that is to say I want my tab to be next to my content without this weird border.
Obviously If I don't force the canvas to be green I'll see something like this:
And so I see there is a gap between my TabbedPanelItem and my content and I don't know how to delete it. I've tried to force border to 0, strip_border to 0, change the height of my widget, force the background_image to "", etc but I am not able to achieve why I want.
Can an expert of Kivy help me out ?
Thank you in advance
It's more tricky that I suspected...
Buttons are stored inside _tab_layout property of TabbedPanel. It's a GridLayout subclass and you can alter its padding property. Here's an example:
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
Builder.load_string('''
<StripLayoust>:
canvas:
Color:
rgba: (0, 1, 0, 1) # green
Rectangle:
size: self.size
pos: self.pos
<MainClass>:
TabbedPanel:
id: panel
do_default_tab: False
TabbedPanelItem:
text: "1"
Widget:
canvas:
Color:
rgb: 0.1, 0.3, .02
Rectangle:
size: self.size
pos: self.pos
TabbedPanelItem:
text: "2"
Widget:
canvas:
Color:
rgb: 0.7, 0.6, .02
Rectangle:
size: self.size
pos: self.pos
''')
class MainClass(FloatLayout):
def __init__(self, *args):
super(MainClass, self).__init__(*args)
self.ids["panel"]._tab_layout.padding = '2dp', '2dp', '2dp', '-2dp'
class TestApp(App):
def build(self):
return MainClass()
if __name__ == '__main__':
TestApp().run()
Note that to remove this border I had to set bottom padding to -2dp and not simply 0dp. Why? Well, as it turned out, every time the panel changes its update_tabs method is called and inside of it there's this cute line:
tab_layout.height = (tab_height + tab_layout.padding[1] +
tab_layout.padding[3] + dp(2))
Adding dp(2) is hard-coded there so I need to use a negative value to counter that.
I use underscore attribute here which is not a part of established public API so this behaviour might change in the future.