How to center GridLayout in kivymd? - python

I have certain news that are filled in first in MD3Card and then lined up in a tabular view in GridLayout with scrolling, but no matter how I tried, it didn't work out to do it all in the center and not on the left edge as in the photo.
Kivymd style:
VK = '''
<Tab>
ScrollView:
md_bg_color: "#f8f8f8"
bar_width: 0
GridLayout:
id: tab_box
padding: "5dp"
cols: 3
spacing: 10
size_hint_y: None
height: self.minimum_height
<MD3Card>
size_hint: None, None
size: "200dp", "230dp"
md_bg_color: "green"
pos_hint: {"center_x": .5, "center_y": .5}
MDBoxLayout:
orientation: "vertical"
FitImage:
source: root.card_image
radius: 6
size_hint_y: 2
MDBoxLayout:
padding: "10dp"
MDLabel:
text: root.card_text
pos_hint: {"center_x": .5, "center_y": .5}
color: "black"
MyBL:
orientation: "vertical"
MDTopAppBar:
title: root.tb_title_text
md_bg_color: "black"
MDBottomNavigation:
panel_color: "black"
text_color_normal: "#999999"
text_color_active: "#ededed"
MDBottomNavigationItem:
name: 'screen 1'
text: 'News'
icon: 'gmail'
badge_icon: "numeric-1"
on_tab_press: root.nb_1()
MDTabs:
id: tabs
background_color: "black"
on_tab_switch: app.on_tab_switch(*args)
MDBottomNavigationItem:
name: 'screen 2'
text: 'TV'
icon: 'twitter'
on_tab_press: root.nb_2()
MDBottomNavigationItem:
name: 'screen 3'
text: 'Radio'
icon: 'linkedin'
on_tab_press: root.nb_3()
'''
Main code:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.properties import StringProperty, ObjectProperty
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.floatlayout import MDFloatLayout
from kivymd.uix.tab import MDTabsBase
from kivymd.uix.card import MDCard
class Tab(MDFloatLayout, MDTabsBase):
'''Class implementing content for a tab.'''
class MD3Card(MDCard):
'''Implements a material design v3 card.'''
card_image = StringProperty()
card_text = StringProperty()
class MyBL(MDBoxLayout):
nb_label_text_1 = StringProperty("News")
nb_label_text_2 = StringProperty("TV")
nb_label_text_3 = StringProperty("Radio")
tb_title_text = StringProperty("News")
text = StringProperty()
def nb_1(self):
self.nb_label_text_1 = "News"
self.tb_title_text = "News"
def nb_2(self):
self.nb_label_text_2 = "TV"
self.tb_title_text = "TV"
def nb_3(self):
self.nb_label_text_3 = "Radio"
self.tb_title_text = "Radio"
class Test(MDApp):
def build(self):
return Builder.load_string(VK)
def on_start(self):
categories = ["main thing","society","economy","health","sports","housing and communal services","politics","culture","science and education",
"world news","opinions","they need help","results of the week","special report","national projects","incidents"]
print(categories)
for categorie in categories:
self.root.ids.tabs.add_widget(
Tab(
title=categorie
)
)
def on_tab_switch(
self, instance_tabs, instance_tab, instance_tab_label, tab_text
):
'''Called when switching tabs.
:type instance_tabs: <kivymd.uix.tab.MDTabs object>;
:param instance_tab: <__main__.Tab object>;
:param instance_tab_label: <kivymd.uix.tab.MDTabsLabel object>;
:param tab_text: text or name icon of tab;
'''
# if tab_text == "главное":
if tab_text == "main thing":
instance_tab.ids.tab_box.clear_widgets()
print(tab_text)
newss = {"news1":"2.jpg", "news2":"2.jpg", "news3":"5.jpg", "news4":"2.jpg", "news5":"5.jpg", "news6":"5.jpg"}
for news in newss.keys():
instance_tab.ids.tab_box.add_widget(
MD3Card(
card_image=newss[news],
card_text=news,
)
)
Test().run()
Is there any other option as a tip for changing the number of cells in a row, let's say if the screen is already the same, not 3 cells, but two, and the rest already goes below.

Code:
<Tab>
ScrollView:
md_bg_color: "#f8f8f8"
bar_width: 0
GridLayout:
id: tab_box
padding: "5dp"
cols: 3
spacing: 10
size_hint_y: None
height: self.minimum_height
Replace with:
<Tab>
ScrollView:
MDBoxLayout:
orientation: "vertical"
adaptive_height: True
MDBoxLayout:
pos_hint: {'center_x': .5}
orientation: "vertical"
adaptive_height: True
adaptive_width: True
GridLayout:
id: tab_box
padding: "5dp"
cols: 3
spacing: 10
size_hint: None, None
size: self.minimum_size
or:
<Tab>
ScrollView:
MDBoxLayout:
orientation: "vertical"
adaptive_height: True
MDBoxLayout:
pos_hint: {'center_x': .5}
orientation: "vertical"
adaptive_height: True
GridLayout:
id: tab_box
padding: "5dp"
cols: 3
spacing: 10
size_hint: None, None
size: self.minimum_size
pos_hint: {'center_x': 0.5, 'center_y': 0.5}

Related

How to use, how to go back to the previous screen from left_action_items of MDTopAppBar in KivyMD?

I created an app with a NavigationDrawer and everything work correctely, but the problem is to return to the first screen. I want to go back to the first screen (the Screen with name: 'Screen_*principal') when I click in the arrow-left in the MDTopAppBar in Login_*screen but nothing that I did worked.
KV file:
#: import RiseInTransition kivy.uix.screenmanager.RiseInTransition
#: import SlideTransition kivy.uix.screenmanager.SlideTransition
<CustomizeScreen#MDBoxLayout>
orientation: 'vertical'
text: ''
padding: 100
MDLabel:
text: root.text
halign: 'center'
pos_hint: {'center_x': .5}
MDFillRoundFlatButton:
text: 'Regresar'
pos_hint: {'center_x': .5}
on_release:
app.root.current = 'screen_principal'
app.root.transition = SlideTransition(direction= 'left' )
<DrawerClickableItem#MDNavigationDrawerItem>
focus_color: "#e7e4c0"
text_color: "#4a4939"
icon_color: "#4a4939"
ripple_color: "#c5bdd2"
selected_color: "#0c6c4d"
<DrawerLabelItem#MDNavigationDrawerItem>
text_color: "#4a4939"
icon_color: "#4a4939"
focus_behavior: False
selected_color: "#4a4939"
_no_ripple_effect: True
<Screen_principal>:
MDNavigationLayout:
MDScreen:
MDTopAppBar:
title: "Navigation Drawer"
elevation: 4
pos_hint: {"top": 1}
md_bg_color: "#e7e4c0"
specific_text_color: "#4a4939"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
MDNavigationDrawer:
id: nav_drawer
radius: (0, 16, 16, 0)
MDNavigationDrawerMenu:
MDNavigationDrawerHeader:
title: "LOCATE YOU"
source: "icono.png"
spacing: "4dp"
padding: "12dp", 0, 0, "56dp"
DrawerClickableItem:
icon: "login"
text_right_color: "#4a4939"
text: "Iniciar Sesion"
on_press:
root.manager.current = "Login_screen"
DrawerClickableItem:
icon: "new-box"
text: "Registrarse"
text_right_color: "#4a4939"
on_press:
root.current = "screen_register"
DrawerClickableItem:
icon: "information-outline"
text: "Informacion"
text_right_color: "#4a4939"
on_press:
root.current = "scr1"
DrawerClickableItem:
icon: "microsoft-teams"
text: "Equipo"
text_right_color: "#4a4939"
on_press:
root.current = "scr1"
<Login_screen>:
MDBoxLayout:
orientation: 'vertical'
MDTopAppBar:
title: "Login"
md_bg_color: "#e7e4c0"
left_action_items: [["arrow-left", lambda *args : setattr(screen_manager, "current", "Screen_principal")]]
MDBoxLayout:
orientation: 'vertical'
size_hint_y: 0.3
Image:
source: 'usuario.png'
pos_hint: {'center_x': 0.5}
MDLabel:
text: 'Iniciar Sesion'
halign: 'center'
color: '#FF5A1E'
font_size: '35dp'
bold: True
pos_hint: {'center_y': .5}
MDBoxLayout:
orientation: 'vertical'
size_hint_y: 0.3
spacing: '12dp'
MDTextField:
id: user
hint_text: "Nombre de usuario"
icon_right: "account"
font_size: '25dp'
icon_right_color: '#FF5A1E'
pos_hint: {'center_x': 0.5}
MDTextField:
id: password
password:True
icon_right: "key-variant"
font_size: '25dp'
icon_right_color: '#FF5A1E'
hint_text: "Contrasena"
pos_hint: {'center_x': 0.5}
MDLabel:
id: signal_login
text: ''
halign: 'center'
color: '#FF5A1E'
font_size: '15dp'
MDBoxLayout:
orientation: 'vertical'
size_hint_y:0.4
spacing: '25dp'
MDFillRoundFlatButton:
id: bt_ingresar
text: 'Ingresar'
pos_hint: {'center_x':0.5}
on_release:
x = app.login_data()
root.current = 'open_screen' if x == True else None
MDFillRoundFlatButton:
md_bg_color: 1,1,1,1
Python file:
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
import requests
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import BooleanProperty, ObjectProperty
Builder.load_file('diseno.kv')
class Screen_principal(Screen):
pass
class Login_screen(Screen):
pass
class TestApp(MDApp):
def build(self):
# Create the screen manager
sm = ScreenManager()
sm.add_widget(Screen_principal(name='Screen_principal'))
sm.add_widget(Login_screen(name='Login_screen'))
return sm
if __name__ == '__main__':
TestApp().run()
I tried a lot of things but nothing work, if someone could fix it I would be very grateful
In your kv, change:
left_action_items: [["arrow-left", lambda *args : setattr(screen_manager, "current", "Screen_principal")]]
to:
left_action_items: [["arrow-left", lambda *args : setattr(root.manager, "current", "Screen_principal")]]
This change accesses the ScreenManager by referencing root.manager, and the root in that context is the Login_screen.

MDCard covers its content, problem with kivyMD inheritance

I created this widget in a .kv file that inherits from MDCard:
<ElementCard#MDCard>:
radius: '10dp'
spacing: '10dp'
padding: '10dp'
image: ''
text: ''
sub_text: ''
orientation: 'vertical'
md_bg_color: 0.87, 0, 0.49
ripple_behavior: True # effect
on_release:
app.root.transition = RiseInTransition()
Image:
source: root.image
halign: 'center'
MDBoxLayout:
orientation: 'vertical'
md_bg_color: 'green'
MDLabel:
text: root.text
color: 'white'
halign: 'center'
MDLabel:
text: root.sub_text
halign: 'center'
and I use it:
<ui>:
...
ElementCard:
text: 'IA'
sub_text: 'Inteligencia artificial'
image: 'images/image1.jpg'
on_release:
root.current = 'screen1'
...
The problem is that the ElementCard widget doesn't show the content:
ElementCard is the purple block and it covers all its content.
When I set the transparency in 0.5 the program looks like this:
50% transparency
The versions are these:
Kivy==2.1.0
kivymd==1.1.1
I've tried rebooting the machine, restarting the virtual environment, reinstalling kivy and kivymd but nothing works.
I think the problem is the inheritance because when I use directly the MDCard like in this code:
MDCard:
radius: '10dp'
spacing: '10dp'
padding: '10dp'
orientation: 'vertical'
md_bg_color: 0.87, 0, 0.49,0.6
ripple_behavior: True # effect
on_release:
app.root.transition = RiseInTransition()
Image:
source: 'images/image1.jpg'
halign: 'center'
MDBoxLayout:
orientation: 'vertical'
md_bg_color: 'green'
MDLabel:
text: 'IA'.
color: 'white'
halign: 'center'
MDLabel:
text: 'Inteligencia artificial'
halign: 'center'
With the last code the program works fine:
MDCard works normally.
main.py full code:
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivymd.app import MDApp
class Ui(ScreenManager):
pass
class MainApp(MDApp):
def build(self):
self.theme_cls.theme_style ='Dark'
self.theme_cls.primary_palette ='Teal'
Builder.load_file("design.kv")
return Ui()
def change_style(self, checked, value):
if value:
self.theme_cls.theme_style ='Dark'
pass
else:
self.theme_cls.theme_style ='Light'
pass
if __name__ == "__main__":
MainApp().run()
design.kv full code:
#:kivy 2.1.0
#:import RiseInTransition kivy.uix.screenmanager.RiseInTransition
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
<CustomizeScreen#MDBoxLayout>:
orientation: 'vertical'
text: ''
padding: 100
MDLabel:
text: root.text
halign: 'center'
pos_hint:{'center_x': 0.5}
MDFillRoundFlatButton:
text: 'REGRESAR'
pos_hint: {'center_x': 0.5}
on_release:
app.root.current = 'screen_principal'
app.root.transition = SlideTransition(direction = 'left')
<ElementCard#MDCard>:
radius: '10dp'
spacing: '10dp'
padding: '10dp'
image: ''
text: ''
sub_text: ''
orientation: 'vertical'
md_bg_color: 0.87, 0, 0.49
ripple_behavior: True # effect
on_release:
app.root.transition = RiseInTransition()
Image:
source: root.image
halign: 'center'
MDBoxLayout:
orientation: 'vertical'
md_bg_color: 'green'
MDLabel:
text: root.text
color: 'white'
halign: 'center'
MDLabel:
text: root.sub_text
halign: 'center'
<ui>:
MDScreen:
name: 'screen_principal'
md_bg_color: "black"
MDBoxLayout:
orientation: "vertical"
MDBoxLayout:
size_hint: 1, 0.2 # x=1 ocupa todo, y=0.2 ocupa 20%
orientation: "horizontal"
padding: '10dp'
MDCard:
radius: '10dp'
padding: '10dp'
line_color: 1,0,1,1
MDLabel:
text: 'APLICACIÓN DE TECNOLOGÍA'
halign: 'center'
pos_hint: {'center_y': 0.5}
MDSwitch:
pos_hint: {'center_y': 0.5}
on_active:
app.change_style(*args)
MDGridLayout:
cols: 3
size_hint: 0.8, 0.8 # x=1 ocupa todo, y=0.8 ocupa 80%
pos_hint: {'center_x': 0.5}
padding: ['10dp','10dp','10dp','10dp']
spacing: '10dp'
ElementCard:
text: 'IA'
sub_text: 'Inteligencia artificial'
image: 'images/image1.jpg'
on_release:
root.current = 'screen1'
I commented this problem in the github kivyMD project, they marked as a bug and give me a couple of options to implement, link to github
Edit:
Thanks for pointing out my mistake with my link.
This is the first option:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.card import MDCard
KV = """
<ElementCard>
MDLabel:
text: "HELLO WORLD"
MDScreen:
ElementCard:
size_hint: 0.5, 0.8
pos_hint: {"center_x": .5, "center_y": .5}
md_bg_color: 0.87, 0, 0.49, 1
"""
class ElementCard(MDCard):
pass
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
MainApp().run()
and the 2nd:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.card import MDCard
KV = """
<ElementCard#MDCard>
MDLabel:
text: "HELLO WORLD"
MDScreen:
ElementCard:
size_hint: 0.5, 0.8
pos_hint: {"center_x": .5, "center_y": .5}
md_bg_color: 0.87, 0, 0.49, 1
"""
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
MainApp().run()
I guess that the kivymd developers will repair this bug in the future.

How to add more than one layout in a single screen in kivymd

I am trying to add a boxlayout to a screen with a boxlayout already, but the contents of the second boxlayout keeps overlaying the contents of the first layout.
I don't think it's my indentation, is there a code I am missing, or anything.
I want the content of the second boxlayout to come last of course. I will really appreciate any help, Thanks in Advance.
here's my code:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
Window.size = (300, 530)
KV = """
MDScreen:
MDBoxLayout:
orientation: 'vertical'
ScrollView:
MDGridLayout:
cols: 1
adaptive_height: True
padding: '10dp', '15dp'
spacing: '15dp'
MDCard:
orientation: 'vertical'
size_hint: 1, None
height: label1.height
# size: 280, 200
MDLabel:
id: label1
markup: True
padding: [15, 1]
size_hint_y: None
height: self.texture_size[1] + 2*self.padding[1]
text:
'''
[size=25][b]Ford[/b][/size]
[b][i]“Make every detail perfect and limit the number of details to perfect.[/b][/i]”
– Jack Dorsey\n
'''
MDCard:
orientation: 'vertical'
size_hint: 1, None
# size: 280, 200
height: label2.height
MDLabel:
id: label2
markup: True
padding: [15, 5]
size_hint_y: None
height: self.texture_size[1] + 2*self.padding[1]
text:
'''
[size=25][b]Ford[/b][/size]
[b][i]“Make every detail perfect and limit the number of details to perfect.[/b][/i]”
– Jack Dorsey\n
'''
MDCard:
orientation: 'vertical'
size_hint: 1, None
# size: 280, 200
height: label2.height
MDLabel:
id: label2
markup: True
padding: [15, 5]
size_hint_y: None
height: self.texture_size[1] + 2*self.padding[1]
text:
'''
[size=25][b]Ford[/b][/size]
[b][i]“Make every detail perfect and limit the number of details to perfect.[/b][/i]”
– Jack Dorsey\n
'''
MDBoxLayout:
orientation: 'vertical'
ScrollView:
MDGridLayout:
cols: 9
spacing: '10dp'
padding: ['10dp', '10dp']
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint: None, None
size: "250dp", "180dp"
elevation: 15
radius: 15
caption: 'Hello dear'
Image:
allow_stretch: True
keep_ratio: False
size_hint_y: 1
source: "C:/Users/HP USER/Downloads/bella_baron.jpg"
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint: None, None
size: "250dp", "180dp"
elevation: 15
radius: 15
caption: 'Hello dear'
Image:
allow_stretch: True
keep_ratio: False
size_hint_y: 1
source: "C:/Users/HP USER/Downloads/bella_baron.jpg"
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint: None, None
size: "250dp", "180dp"
elevation: 15
radius: 15
caption: 'Hello dear'
Image:
allow_stretch: True
keep_ratio: False
size_hint_y: 1
source: "C:/Users/HP USER/Downloads/bella_baron.jpg"
"""
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
Example().run()
From Kivy docs:
The class RelativeLayout behaves just like the regular
FloatLayout except that its child widgets are positioned
relative to the layout.
You have to put everything inside a BoxLayout to override the default RelativeLayout behaviour of MDScreen:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
Window.size = (300, 530)
KV = """
<MyImageCard#MDCard>
source: ''
caption:''
ripple_behavior: True
orientation: 'vertical'
size_hint: None, None
size: "250dp", "180dp"
elevation: 15
radius: 15
padding: "8dp"
MDLabel:
text: root.caption
theme_text_color: "Secondary"
adaptive_height: True
MDSeparator:
height: "1dp"
Image:
allow_stretch: True
keep_ratio: False
size_hint_y: 1
source: root.source
<MyTextCard#MDCard>:
text:""
orientation: 'vertical'
size_hint: 1, None
height: child_label.height
MDLabel:
id: child_label
markup: True
padding: [15, 1]
size_hint_y: None
height: self.texture_size[1] + 2*self.padding[1]
text:root.text
MDScreen:
image: "C:/Users/HP USER/Downloads/bella_baron.jpg"
text:'[size=25][b]Ford[/b][/size][b][i]\\n"Make every detail perfect and limit the number of details to perfect."[/b][/i] \\n– Jack Dorsey'
MDBoxLayout:
orientation: 'vertical'
size_hint: 1, 1
pos_hint:{"center_x":.5,"center_y":.5}
ScrollView:
MDGridLayout:
cols: 1
adaptive_height: True
padding: '10dp', '15dp'
spacing: '15dp'
MyTextCard:
text:root.text
MyTextCard:
text:root.text
MyTextCard:
text:root.text
MyTextCard:
text:root.text
MyTextCard:
text:root.text
MDBoxLayout:
orientation: 'vertical'
size_hint: 1, None
height: 400
ScrollView:
MDGridLayout:
cols: 3
adaptive_height: True
adaptive_width: True
spacing: '10dp'
padding: ['10dp', '10dp']
MyImageCard:
source: root.image
caption: 'Hello dear'
MyImageCard:
source: root.image
caption: 'Lovely'
MyImageCard:
source: root.image
caption: 'See you'
MyImageCard:
source: root.image
caption: 'Later'
MyImageCard:
source: root.image
caption: 'Forever'
MyImageCard:
source: root.image
caption: 'Good Bye'
"""
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
Example().run()
Also you were missing an indentation level after the second Scrollview, but that was not the source of the problem :)
You can use pos_hint and size_hint to get what I think you want. Start your kv with:
MDScreen:
MDBoxLayout:
size_hint: 1, 0.5 # use half the available height of the MDScreen
pos_hint: {'top':1} # position at the top of the MDSCreen
and for the second MDBoxLayout add similar code:
MDBoxLayout:
size_hint: 1, 0.5 # use half the available height of the MDScreen
pos_hint: {'y':0} # position at the bottom of the MDSCreen

Kivy Scrollview: AttributeError: 'NoneType' object has no attribute 'bind'

Good Morning,
I'm new in this website but I constantly control topics that help me coding. I just started to learn coding and I'm new on python that i think it's one of the best.
By the way: I'm working on Kivy for build an app formed by cards that user can collect and consult. I built the cards (with MDCards) but the screen is blocked and if I add more than 5 cards they're invisible (out of screen). I'm trying to add a scrollview on the GridLayout in KV. Following some topic i found this way.
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
from kivy.uix.gridlayout import GridLayout
from kivy.app import runTouchApp
from kivy.uix.button import Button
KV = """
Screen:
Controller:
layout_content: layout_content
BoxLayout:
id: bl
orientation: 'vertical'
padding: 10, 10
row_default_height: '48dp'
row_force_default: True
spacing: 10, 10
ScrollView:
size: self.size
GridLayout:
id: layout_content
size_hint_y: None
cols: 1
row_default_height: '20dp'
row_force_default: True
spacing: 0, 0
padding: 0, 0
MDCard:
id: tel1
orientation: "vertical"
padding: "8dp"
size_hint: None, None
size: "180dp", "280dp"
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDLabel:
text: "Tele 1"
theme_text_color: "Secondary"
size_hint_y: None
height: self.texture_size[1]
MDSeparator:
height: "5dp"
width: "5dp"
MDLabel:
text: "Descrizione del primo"
MDCard:
id: tel2
orientation: "vertical"
padding: "8dp"
size_hint: None, None
size: "180dp", "280dp"
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDLabel:
text: "Tele 2"
theme_text_color: "Secondary"
size_hint_y: None
height: self.texture_size[1]
MDSeparator:
height: "5dp"
width: "5dp"
MDLabel:
text: "Descrizione del secondo"
MDCard:
id: tel2
orientation: "vertical"
padding: "8dp"
size_hint: None, None
size: "180dp", "280dp"
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDLabel:
text: "Tele 3"
theme_text_color: "Secondary"
size_hint_y: None
height: self.texture_size[1]
MDSeparator:
height: "5dp"
width: "5dp"
MDLabel:
text: "Descrizione del terzo"
MDCard:
id:tel4
orientation: "vertical"
padding: "8dp"
size_hint: None, None
size: "180dp", "280dp"
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDLabel:
text: "Telefilm 4"
theme_text_color: "Secondary"
size_hint_y: None
height: self.texture_size[1]
MDSeparator:
height: "5dp"
width: "5dp"
MDLabel:
text: "Descrizione del quarto"
MDCard:
id:tel5
orientation: "vertical"
padding: "8dp"
size_hint: None, None
size: "180dp", "280dp"
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDLabel:
text: "Tele 5"
theme_text_color: "Secondary"
size_hint_y: None
height: self.texture_size[1]
MDSeparator:
height: "5dp"
width: "5dp"
MDLabel:
text: "Descrizione del quinto"
"""
class Controller(FloatLayout):
layout_content = ObjectProperty(None)
def __init__(self, **kwargs):
super(Controller, self).__init__(**kwargs)
self.layout_content.bind(minimum_height=self.layout_content.setter('height'))
class MainApp(MDApp):
def build(self):
self.title = "LukeFlix"
self.theme_cls.theme_style = "Light"
self.theme_cls.primary_palette = "Red"
return Builder.load_string(KV)
MainApp().run()
But I get this Error:
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/pythonProject3APP/main.py", line 140, in <module>
MainApp().run()
File "C:\Users\User\PycharmProjects\pythonProject3APP\venv\lib\site-packages\kivy\app.py", line 949, in run
self._run_prepare()
File "C:\Users\User\PycharmProjects\pythonProject3APP\venv\lib\site-packages\kivy\app.py", line 919, in _run_prepare
root = self.build()
File "C:/Users/User/PycharmProjects/pythonProject3APP/main.py", line 132, in build
return Builder.load_string(KV)
File "C:\Users\User\PycharmProjects\pythonProject3APP\venv\lib\site-packages\kivy\lang\builder.py", line 408, in load_string
self._apply_rule(
File "C:\Users\User\PycharmProjects\pythonProject3APP\venv\lib\site-packages\kivy\lang\builder.py", line 659, in _apply_rule
child = cls(__no_builder=True)
File "C:/Users/User/PycharmProjects/pythonProject3APP/main.py", line 125, in __init__
self.layout_content.bind(minimum_height=self.layout_content.setter('height'))
AttributeError: 'NoneType' object has no attribute 'bind'
Process finished with exit code 1
How can I fix it?
The error is caused by the __init__() method of the Controller class. At that point, the layout_content property has not yet been assigned. You can eliminate that __init__() method by redefining Controller like this:
class Controller(FloatLayout):
pass
And then accomplish the same desired result by modifying the ScrollView section of your kv:
ScrollView:
# size: self.size # this has no effect
GridLayout:
id: layout_content
size_hint_y: None
cols: 1
# row_default_height: '20dp'
# row_force_default: True
height: self.minimum_height
spacing: 0, 0
padding: 0, 0
Note the height: self.minimum_height line, which does what your __init__() method was trying to do. Also, the row defaults were forcing the rows in the GridLayout to a too small height.

Python/Kivy : not working properly vertical scrollbar in dynamic row

I have two files demo.py and demo.kv
I have a button +Add More which add row dynamic.I am trying to add vertical scrollbar in dynamic row using ScrollView:.But its not working properly.
its mean when i add row in scrollview that row having extra space in scrollview i want add rows without any spacing.
ScrollView:
BoxLayout:
orientation: "horizontal"
size_hint_y: None
height: 500
Rows:
id: rows
demo.py
import kivy
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (500, 400)
class user(Screen):
def add_more(self):
self.ids.rows.add_row()
class Row(BoxLayout):
button_text = StringProperty("")
class Rows(BoxLayout):
orientation = "vertical"
row_count = 0
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
self.add_row()
def add_row(self):
self.row_count += 1
self.add_widget(Row(button_text=str(self.row_count)))
class Test(App):
def build(self):
self.root = Builder.load_file('demo.kv')
return self.root
if __name__ == '__main__':
Test().run()
demo.kv
<Button#Button>:
font_size: 15
font_name: 'Verdana'
<Label#Label>:
font_size: 15
font_name: 'Verdana'
<TextInput#TextInput>:
font_size: 15
font_name: 'Verdana'
padding_y: 3
<Row>:
GridLayout:
cols: 2
row_force_default: True
row_default_height: 40
Button:
text: root.button_text
size_hint_x: None
top: 200
Button:
text: 'World 1'
width: 300
user:
BoxLayout:
orientation: "vertical"
padding : 20, 5
BoxLayout:
orientation: "horizontal"
#padding : 10, 10
spacing: 10, 10
size: 450, 40
size_hint: None, None
Label:
size_hint_x: .2
text: "Test 1"
text_size: self.size
valign: 'bottom'
halign: 'center'
Label:
size_hint_x: .8
text: "Test 2"
text_size: self.size
valign: 'bottom'
halign: 'center'
ScrollView:
BoxLayout:
orientation: "horizontal"
size_hint_y: None
height: 500
Rows:
id: rows
BoxLayout:
orientation: "horizontal"
size_hint_x: .2
size_hint_y: .2
Button:
text: "+Add More"
on_press: root.add_more()
BoxLayout:
orientation: "horizontal"
padding : 10, 5
spacing: 10, 10
size_hint: .5, .35
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
Button:
text: 'Cancel'
any help would be greatly appreciated.
If I have understood what you want, you have too many nested Layouts, that are unnecessary. Rows should be the main layout of your ScrollView.
On the other hand, Rows should always have the lowest possible height to contain their widgets (minimun_height property), not a fixed size.
Demo.py:
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (500, 400)
class User(Screen):
def add_more(self):
self.ids.rows.add_row()
class Row(BoxLayout):
button_text = StringProperty("")
class Rows(BoxLayout):
row_count = 0
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
self.add_row()
def add_row(self):
self.row_count += 1
self.add_widget(Row(button_text=str(self.row_count)))
class Test(App):
def build(self):
self.root = Builder.load_file('Demo.kv')
return self.root
if __name__ == '__main__':
Test().run()
Demo.kv:
<Button#Button>:
font_size: 15
font_name: 'Verdana'
<Label#Label>:
font_size: 15
font_name: 'Verdana'
<TextInput#TextInput>:
font_size: 15
font_name: 'Verdana'
padding_y: 3
<Row>:
size_hint_y: None
height: self.minimum_height
height: 40
Button:
text: root.button_text
size_hint_x: None
top: 200
Button:
text: 'World 1'
width: 300
<Rows>:
size_hint_y: None
height: self.minimum_height
orientation: "vertical"
User:
BoxLayout:
orientation: "vertical"
padding : 20, 5
BoxLayout:
orientation: "horizontal"
#padding : 10, 10
spacing: 10, 10
size: 450, 40
size_hint: None, None
Label:
size_hint_x: .2
text: "Test 1"
text_size: self.size
valign: 'bottom'
halign: 'center'
Label:
size_hint_x: .8
text: "Test 2"
text_size: self.size
valign: 'bottom'
halign: 'center'
ScrollView:
Rows:
id: rows
BoxLayout:
orientation: "horizontal"
size_hint_x: .2
size_hint_y: .2
Button:
text: "+Add More"
on_press: root.add_more()
BoxLayout:
orientation: "horizontal"
padding : 10, 5
spacing: 10, 10
size_hint: .5, .35
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
Button:
text: 'Cancel'

Categories

Resources