How can I change the height of Boxlayout Dynamically? - python

I am trying to change Boxlayout height dynamically. There will an empty Boxlayout at the beginning, then with a ToggleButton I will add Buttons on that Boxlayout vertically. But this Boxlayout locates in Gridlayout which has ScrollView. And the number of buttons I will add will change, so the height of the box layout should change too. But it doesn't change. Could you please help.
Here is my main.py:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty
from kivy.properties import ListProperty
from collections import OrderedDict
data1=["mother","father","son"]
data2=["uncle","aunt","grandfather"]
data3=["jack","mike","simon"]
data4=["1898","1975","1985","1885"]
class MainWidget(Widget):
an0=tuple(list(OrderedDict.fromkeys(data1)))
cal5= ObjectProperty()
def btn10(self,text):
if self.cal5:
self.cal5.parent.remove_widget(self.cal5) #EVERY TIME I NEED TO REMOVE IT BECAUSE MY BUTTON QUANTITIY AND TEXT WILL CHANGE DUE TO TOGGLE BUTTON SELECTION
self.cal5 =ModelSpecifications()
a=data2
b=data3
c=data4
mi=[]
n=0
while n < len(a):
aba=(str(a[n])+"\n"+str(b[n])+"\n"+str(c[n]))
mi.append(aba)
n+=1
for i in mi:
self.b1=Button(text=str(i),size_hint=(1,None),height="10dp")
self.cal5.add_widget(self.b1)
self.ids.scd.add_widget(self.cal5, index=3) #I ADD THE BUTTONS IN HERE
class SecondPage(ScrollView):
pass
some_number=120
calculated_height=(str(some_number)+"dp") #<------I CAN CHANGE THE HEIGHT AT THE BEGINING BUT IT DOSENT CHANGE THE HEIGHT DYNAMICALLY
class ModelSpecifications(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.size_hint=(1,None)
self.height=calculated_height
class Calculation(GridLayout):
pass
class MyApp(App):
pass
MyApp().run()
And here is my my.kv file:
#:import C kivy.utils.get_color_from_hex
MainWidget:
<MainWidget>:
ScreenManager:
id: scmanager
size: root.width, root.height
Screen:
id: scndpage
name: "second"
SecondPage:
Calculation:
id:scd
cols:1
height: self.minimum_height
row_default_height: "70dp" #<---THIS HEIGHT MUST BE SPECIFY BECAUSE OF SCROLLWIEW
size_hint_y: None
spacing:"10dp"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size_hint: 1, None
height: "50dp"
pading:"10dp"
spacing:"10dp"
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
Label:
text:"Name:"
color: 0,0,0,1
TextInput:
text:"---"
color: 0,0,0,1
Label:
text:"Surname:"
color: 0,0,0,1
TextInput:
text:"-----"
color: 0,0,0,1
BoxLayout:
id:scdd
size_hint: 1, 1
height: "100dp"
orientation: "vertical"
BoxLayout:
size_hint: 1, None
height: "50dp"
orientation: "horizontal"
Label:
text: " Sellection:"
color: 0,0,0,1
Spinner:
text: 'Home'
values: root.an0
on_text: app.root.btn10(self.text)
Button:
text:" Calculate"
Button:
text:"Sellect"
Button:
text:"Back"
<ModelSpecifications>: #<---------HOW CAN I DYNAMICALLY CHANGE THE HEIGHT OF THIS WIDGET ?
id:anss
pading:"10dp"
spacing:"10dp"
orientation: "vertical"
canvas.before:
Color:
rgba: (C('EBE4E4'))
RoundedRectangle:
size: self.size
pos: self.pos
radius: [15]
I want to change the height in the python script because I will get the information from another function as variable.
Please run the file. Looking forward to your comments.

Related

How Can I Remove BoxLayout?

I want to remove a Boxlayout in my widget, but I cant.
There is a Boxlayout at the begining of the app called "Speca". After my sellections it must be removed.
When you run the app, sellect something in "Home" Spinner and click any of the new Toggle buttons.
Wtih the press of any of the Toggle buttons "Speca" must disappear.
Please help.
Here is main.py:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty
from kivy.properties import ListProperty
from collections import OrderedDict
from kivy.uix.togglebutton import ToggleButton
data1=["mother","father","son"]
data2=["uncle","aunt","grandfather"]
data3=["jack","mike","simon"]
data4=["1898","1975","1985","1885"]
amd="0dp"
class MainWidget(Widget):
def remove_layout(self, *ignore):
self.remove_widget(self.layout)
global amd
an0=tuple(list(OrderedDict.fromkeys(data1)))
cal5= ObjectProperty()
cal6= ObjectProperty()
def btn10(self,text):
if self.cal5:
self.cal5.parent.remove_widget(self.cal5)
self.cal5 =ModelSpecifications()
a=data2
b=data3
c=data4
mi=[]
n=0
while n < len(a):
aba=n
mi.append(aba)
n+=1
for i in mi:
self.b1=MyTButton(text=str(i),size_hint=(1,None),height="100dp",group="selections")
self.cal5.add_widget(self.b1)
self.ids.scd.add_widget(self.cal5, index=3)
def on_state(self, togglebutton): #<----THIS IS THE TUGGLEBUTTON I WANT USE
global amd
tb = togglebutton
text1=tb.text
if text1=="0":
amd="50dp"
elif text1=="1":
amd="100dp"
else:
amd="200dp"
if self.cal6:
self.cal6.parent.remove_widget(self.cal6)
self.cal6 =Spec()
self.ids.scd.add_widget(self.cal6, index=2)
class SecondPage(ScrollView):
pass
class Speca(BoxLayout): #<------ THIS IS THE BOXLAYOUT I WANT TO REMOVE
pass
class Spec(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.size_hint=(1,None)
self.height=amd
class MyTButton(ToggleButton):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class ModelSpecifications(BoxLayout): #this is the class I want add after my spinner selection
pass
class Calculation(GridLayout):
pass
class MyApp(App):
pass
MyApp().run()
here is my.kv :
MainWidget:
<MainWidget>:
hideable: hideable
ScreenManager:
id: scmanager
size: root.width, root.height
Screen:
id: scndpage
name: "second"
SecondPage:
Calculation:
id:scd
cols:1
height: self.minimum_height
row_default_height: "70dp"
size_hint_y: None
spacing:"10dp"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size_hint: 1, None
height: "50dp"
pading:"10dp"
spacing:"10dp"
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
Label:
text:"Name:"
color: 0,0,0,1
TextInput:
text:"---"
color: 0,0,0,1
Label:
text:"Surname:"
color: 0,0,0,1
TextInput:
text:"-----"
color: 0,0,0,1
BoxLayout:
id:scdd
size_hint: 1, 1
height: "100dp"
orientation: "vertical"
BoxLayout:
size_hint: 1, None
height: "50dp"
orientation: "horizontal"
Label:
text: " Sellection:"
color: 0,0,0,1
Spinner:
text: 'Home'
values: root.an0
on_text: app.root.btn10(self.text)
Speca: #<------ THIS IS THE BOXLAYOUT I WANT TO REMOVE
Button:
text:" Calculate"
Button:
text:"Sellect"
Button:
text:"Back"
<ModelSpecifications>:
id:anss
pading:"10dp"
spacing:"10dp"
size_hint: 1, None
height: "100dp"
orientation: "horizontal"
<MyTButton#ToggleButton>: #<----THIS IS THE TUGGLEBUTTON I WANT USE
on_state:
app.root.on_state(self)
<Speca>: #<------ THIS IS THE BOXLAYOUT I WANT TO REMOVE
orientation:"vertical"
Label:
color: (1,1,0,1)
text:"I WANT TO REMOVE THIS PART WHEN I PRESS ANY OF TOGGLE BUTTONS"
Please run the app and see it.
Looks to me like speca is a child of the calculation widget with ID scd. So give speca an ID and then Remove speca via ids in on_srate python function.
Kv
SecondPage:
Calculation:
id:scd
speca:
id: speca
py
def on_state():
self.root.ids.scd.remove_widget(self.root.ids.speca)
YES.
When I make those changes;
Kv
SecondPage:
Calculation:
id:scd
speca:
id: speca
py
def on_state():
self.ids.scd.remove_widget(self.ids.speca)
It works.

How can I clear widget in kivy?

I am making a selection app. I am using a spinner for multiple choises. After spinner selection I want to add 3 different buttons, which are related to spinner selection. In every selection in spinner those old buttons replace with new ones.
So far I can add different buttons after every selection. However, the buttons are keep adding. I need to clear the old buttons first after every spinner selection.
My class, which contains buttons is "ModelSpecifications".
Long story short, there is something wrong in clear_widgets(). It cant reach "ModelSpecifications".
Here is my main.py;
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty
from kivy.properties import ListProperty
from collections import OrderedDict
data1=["mother","father","son"]
data2=["uncle","aunt","grandfather"]
data3=["jack","mike","simon"]
data4=["1898","1975","1985","1885"]
class MainWidget(Widget):
an0=tuple(list(OrderedDict.fromkeys(data1)))
cal5= ObjectProperty()
def btn10(self,text):
#----------here is the part I want to clear the buttons first:
#ModelSpecifications.clear_widgets(ModelSpecifications)
# or
#self.ids["anss"].clear_widgets()
# after that I will add new buttons:
self.cal5 =ModelSpecifications()
a=data2
b=data3
c=data4
mi=[]
n=0
while n < len(a):
aba=(str(a[n])+"\n"+str(b[n])+"\n"+str(c[n]))
mi.append(aba)
n+=1
for i in mi:
self.b1=Button(text=str(i),size_hint=(1,None),height="100dp")
self.cal5.add_widget(self.b1)
self.ids.scd.add_widget(self.cal5, index=3) #here id.scd is the class that ModelSpecifications class is added. And it works fine.
class SecondPage(ScrollView):
pass
class ModelSpecifications(BoxLayout): #this is the class I want add after my spinner selection
pass
class Calculation(GridLayout):
pass
class MyApp(App):
pass
MyApp().run()
And here is my.kv ;
MainWidget:
<MainWidget>:
ScreenManager:
id: scmanager
size: root.width, root.height
Screen:
id: scndpage
name: "second"
SecondPage:
Calculation:
id:scd
cols:1
height: self.minimum_height
row_default_height: "70dp"
size_hint_y: None
spacing:"10dp"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size_hint: 1, None
height: "50dp"
pading:"10dp"
spacing:"10dp"
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
Label:
text:"Name:"
color: 0,0,0,1
TextInput:
text:"---"
color: 0,0,0,1
Label:
text:"Surname:"
color: 0,0,0,1
TextInput:
text:"-----"
color: 0,0,0,1
BoxLayout:
id:scdd
size_hint: 1, 1
height: "100dp"
orientation: "vertical"
BoxLayout:
size_hint: 1, None
height: "50dp"
orientation: "horizontal"
Label:
text: " Sellection:"
color: 0,0,0,1
Spinner:
text: 'Home'
values: root.an0
on_text: app.root.btn10(self.text)
Button:
text:" Calculate"
Button:
text:"Sellect"
Button:
text:"Back"
<ModelSpecifications>:
id:anss #HERE IS MY CLASS THAT I WANT TO CLEAR AND ADD AFTER EVERY SPINNER SELECTION
pading:"10dp"
spacing:"10dp"
size_hint: 1, None
height: "100dp"
orientation: "horizontal"
When you run this code sellect something in spinner. You will see in every selection, app keeps add more buttons;
In your btn10() method, just add:
if self.cal5:
self.cal5.parent.remove_widget(self.cal5)
before the line:
self.cal5 = ModelSpecifications()

How to add custom widget to another custom widget in kivy

I am pretty new to the kivy language and faced this problem when try to run the following code. it just runs without any errors. But it just only generate a blank application. without any widgets.
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.gridlayout import GridLayout
from kivymd.uix.boxlayout import MDBoxLayout
kv = """
<SCManager>:
Screen:
c_screen:
<c_screen>:
cols: 2
canvas.before:
Color:
rgba: 1,0,0,1
Rectangle:
pos: self.pos
size: self.size
MDBoxLayout:
md_bg_color: (1, 1, 1 ,1)
padding: 10
adaptive_height: True
MDLabel:
text: "helow 2"
color: (0.0003, 0.34, 0.60,1)
font_style: "H6"
halign: "left"
adaptive_height: True
<navigator>:
canvas.before:
Color:
rgba: 1,1,0,1
Rectangle:
pos: self.pos
size: self.size
orientation: "vertical"
MDLabel:
text: "hellow"
adaptive_height: True
MDList:
OneLineAvatarListItem:
text : "Dashboard"
IconLeftWidgetWithoutTouch:
icon: "view-dashboard"
OneLineAvatarListItem:
text : "Manage Users"
IconLeftWidgetWithoutTouch:
icon: "account"
MDRoundFlatIconButton:
text: "bye"
font_size: 11
"""
class SCManager(ScreenManager):
pass
class navigator(MDBoxLayout):
pass
class c_screen(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.n = navigator()
self.add_widget(self.n)
class test(MDApp):
def build(self):
Builder.load_string(kv)
return SCManager()
if __name__ == '__main__':
test().run()
But if i add another widget(a label) to Screen from kv string, it works fine or if i use add_widget(c_screen) in SCManager it works fine.But i need to add c_screen class from the kv string. Is there any way to add widgets without adding any widgets to Screen??
here is the working code
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.gridlayout import GridLayout
from kivymd.uix.boxlayout import MDBoxLayout
kv = """
<SCManager>:
Screen:
MDLabel:
text: "helow 2"
adaptive_height: True
c_screen:
<c_screen>:
cols: 2
canvas.before:
Color:
rgba: 1,0,0,1
Rectangle:
pos: self.pos
size: self.size
MDBoxLayout:
md_bg_color: (1, 1, 1 ,1)
adaptive_height: True
MDLabel:
text: "helow 2"
adaptive_height: True
<navigator>:
canvas.before:
Color:
rgba: 1,1,0,1
Rectangle:
pos: self.pos
size: self.size
orientation: "vertical"
MDLabel:
text: "hellow"
adaptive_height: True
MDList:
OneLineAvatarListItem:
text : "Dashboard"
IconLeftWidgetWithoutTouch:
icon: "view-dashboard"
OneLineAvatarListItem:
text : "Manage Users"
IconLeftWidgetWithoutTouch:
icon: "account"
MDRoundFlatIconButton:
text: "bye"
font_size: 11
"""
class SCManager(ScreenManager):
pass
class navigator(MDBoxLayout):
pass
class c_screen(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.n = navigator()
self.add_widget(self.n)
class test(MDApp):
def build(self):
Builder.load_string(kv)
return SCManager()
if __name__ == '__main__':
test().run()

How do you change the background color of a TabbedPanelItem in Kivy

I want to change the background color on my tabs and change from the default grey color, but I can't manage to find out how to do it.
I have tried defining a canvas but that just ends up creating like a colored layer over the tab and then I can't read the text on the tab.
my .py file:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class IntroScreen(Screen):
pass
class MainScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
app=Builder.load_file("main.kv")
class mainApp(App):
def build(self):
return app
mainApp().run()
main.kv file:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import get_color_from_hex kivy.utils.get_color_from_hex
ScreenManagement:
transition: FadeTransition()
MainScreen:
<MainScreen>:
name: "main_screen"
BoxLayout:
orientation: "horizontal"
height: 30
BoxLayout:
orientation: "horizontal"
TabbedPanel:
do_default_tab: False
tab_width: self.parent.width/2
canvas.before:
Color:
rgb: get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
TabbedPanelItem:
text: "Tab 1"
color: get_color_from_hex("#ffffff")
markup: True
Label:
text: "contents of tab 1"
color: get_color_from_hex("#000000")
canvas.before:
Color:
rgb: get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
TabbedPanelItem:
text: "Tab 2"
markup: True
Label:
text: "contents of tab 2"
color: get_color_from_hex("#000000")
canvas.before:
Color:
rgb: get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
The tab is a class of TabbedPanelHeader and they have the following properties just like Button widget.
Example
Add the following into kv file:
<TabbedPanelHeader>:
background_normal: 'blue.png'
background_down: 'red.png'
Output

Kivy 1.10.1 Slider duplicating itself

I'm currently trying to create a simple Slider that will control the size of text in my application. The problem I'm running into though is that even though the slider functions as I intended, it seems to create another version of itself beneath the first slider that can't be moved. You can see how it looks in the provided image here [alt text: a screenshot of a rudimentary user interface showing a kivy slider. The slider has been moved forward behind it there is another copy in the default position] (as you can see the Label text inside the BoxLayout is also getting overlapped). I'm currently using Kivy 1.10.1 and Python 3.7.2.
Here is my Python script:
# -*- coding: utf-8 -*-
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.actionbar import ActionBar
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.graphics.vertex_instructions import (Rectangle, Ellipse, Line)
from kivy.graphics.context_instructions import Color
from kivy.uix.checkbox import CheckBox
from kivy.uix.slider import Slider
#Window.size = (360/1.2,740/1.2)
class HomeScreen(Screen):
pass
class OptionsScreen(Screen):
pass
class TutorialScreen(Screen):
pass
class ScreenController(ScreenManager):
pass
look = Builder.load_file('main.kv')
class MainApp(App):
def build(self):
return look
if __name__ == '__main__':
MainApp().run()
And here is the relevant piece of Kivy language meant to create the slider on my
<OptionsScreen>
name: 'option'
BoxLayout:
orientation:'vertical'
BoxLayout:
orientation:'horizontal'
size_hint_y: 1/3
Label:
text:'Text size'
font_size: textsize.value
size_hint_x:.5
Slider:
id:textsize
min: 5
max: 25
value:15
step: 1
size_hint_x:.5
Though if you want to read the entire Kivy language document I'm posting it here as well.
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
# Reference main.py
#: import main main
#: import Slider kivy.uix.slider
#: import ActionBar kivy.uix.actionbar
#: import Window kivy.core.window
ScreenController:
transition: FadeTransition()
HomeScreen:
OptionsScreen:
TutorialScreen:
<HomeScreen>
name: 'home'
BoxLayout:
id:'hem'
orientation:'vertical'
BoxLayout:
size_hint_x: 1
orientation:'horizontal'
canvas:
Color:
rgba: 0,1,0,1
Rectangle
size: self.size
pos: self.pos
BoxLayout:
orientation:'horizontal'
BoxLayout:
size_hint_x: .5
orientation:'horizontal'
canvas:
Color:
rgba: 1,0,1,1
Rectangle
size: self.size
pos: self.pos
BoxLayout:
size_hint_x: .5
orientation:'horizontal'
canvas:
Color:
rgba: 1,1,0,1
Rectangle
size: self.size
pos: self.pos
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: 'Fredde & Kribbas kivy'
with_previous: False
ActionOverflow:
ActionGroup:
text: 'Group1'
ActionButton:
text: 'home'
on_touch_down: app.root.current = 'home'
ActionButton:
text: 'Options'
on_touch_down: app.root.current = 'option'
ActionButton:
text: 'Tutorial'
on_touch_down: app.root.current = 'tut'
<OptionsScreen>
name: 'option'
BoxLayout:
orientation:'vertical'
BoxLayout:
orientation:'horizontal'
size_hint_y: 1/3
Label:
text:'Text size'
font_size: textsize.value
size_hint_x:.5
Slider:
id:textsize
min: 5
max: 25
value:15
step: 1
size_hint_x:.5
BoxLayout:
#fontsize checkbox
orientation:'horizontal'
size_hint_y: 1/3
BoxLayout:
orientation:'vertical'
Label:
text: 'Nightmode'
CheckBox:
id:default
size_hint_y: None
active: True
height:'50dp'
group:'g1'
BoxLayout:
orientation:'vertical'
Label:
text: 'Daymode'
CheckBox:
id:stor
size_hint_y: None
height:'50dp'
group:'g1'
BoxLayout:
orientation:'horizontal'
size_hint_y: 1/3
canvas:
Color:
rgba: 0,0,1,1
Rectangle
size: self.size
pos: self.pos
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: 'Fredde & Kribbas kivy'
with_previous: False
ActionOverflow:
ActionGroup:
text: 'Group1'
ActionButton:
text: 'home'
on_touch_down: app.root.current = 'home'
ActionButton:
text: 'Options'
on_touch_down: app.root.current = 'option'
ActionButton:
text: 'Tutorial'
on_touch_down: app.root.current = 'tut'
<TutorialScreen>
name: 'tut'
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: 'Fredde & Kribbas kivy'
with_previous: False
ActionOverflow:
ActionGroup:
text: 'Group1'
ActionButton:
text: 'home'
on_touch_down: app.root.current = 'home'
ActionButton:
text: 'Options'
on_touch_down: app.root.current = 'option'
ActionButton:
text: 'Tutorial'
on_touch_down: app.root.current = 'tut'
Does anyone know why I might be having this issue? I'm fairly new to kivy but I've played around with the slider before and never had these issues until now.
You don't need to load your kv file inside your python code since you already named your kv file as main.kv.
You can try to remove this line:
look = Builder.load_file('main.kv')
and change this line:
return look
to:
pass

Categories