how can i create a KivyMD card with adjustable height - kivy

I am trying to make a kivymd card which has an adjustable height but is not able to. I would like the card to adjust its height according to the items called in it. also, all the items called in it to feet in. am not sure if it's ok to use a card or just a boxlayout in this type of application
from kivy.uix.screenmanager import Screen
from kivymd.app import MDApp
#from kivymd.uix.button import MDCard
from kivymd.uix.card import MDCard,MDSeparator
from kivymd.uix.label import MDLabel
from kivymd.uix.list import TwoLineAvatarListItem,ImageLeftWidget
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
KV = '''
<Post_message>:
MDBoxLayout:
orientation: "vertical"
id: box_bottom
adaptive_height: True
padding: "20dp", "5dp", 0, 0
size_hint_y: None
spacing: "1dp"
MDLabel:
text:"Midrange and flagship."
size_hint_y: None
height: self.texture_size[1]
pos_hint: {"center_y": .5}
theme_text_color: "Primary"
<Post_profile>:
MDBoxLayout:
adaptive_height: True
padding:"-17dp", 0, 0, 0
TwoLineIconListItem:
text:f"[color=#00ACC1]Profile name[/color]"
markup: True
secondary_text: "Location"
height: dp(48)
divider: None
_txt_bot_pad: dp(5)
IconLeftWidget:
icon:'kivymd_logo.png'
<Post_bottom_bar>:
orientation: "horizontal"
adaptive_height: True
MDBoxLayout:
orientation: "horizontal"
adaptive_height: True
padding: "25dp", 0, 0, "15dp"
MDLabel:
text:f"[color=#00ACC1]2.jun.2020[/color]"
markup: True
size_hint_y: None
height: self.texture_size[1]
pos_hint: {"center_y": .5}
MDBoxLayout:
orientation: "horizontal"
adaptive_height: True
padding: "30dp", 0, 0, 0
MDIconButton:
icon: "heart-outline"
on_release:
#self.grow()
self.icon = "heart" if self.icon == "heart-outline" else "heart-outline"
MDIconButton:
icon: "message"
on_release:
#self.grow()
MDIconButton:
icon: "dots-vertical"
on_release:
#self.grow()
'''
class Post_bottom_bar(BoxLayout):
pass
class Post_profile(BoxLayout):
pass
class Post_message(BoxLayout):
pass
class MainApp(MDApp):
def build(self):
self.theme_cls.theme_style="Dark"
Builder.load_string(KV)
screen = Screen()
post_card = MDCard(
padding = [0, 0, 0, 0],
spacing = "5dp",
border_radius = 20,
radius = [15, 15, 15, 15],
orientation= "vertical",
size_hint= [1, None],
elevation=9,
)
post_card.add_widget(Post_profile())
post_card.add_widget(Post_message())
post_card.add_widget(Post_bottom_bar())
screen.add_widget(post_card)
return screen
MainApp().run()
am additional corrections and suggestions are welcomed

Related

Unknown class <DrawerClickableItem>"

i want to add items to NavigationDrawer but i get this "Unknown class " errors instead.
i tried defining a Class "DrawerClickableItem" but it wouldn't work instead i get errors. i have tried several options that seem to work but "DrawerClickableItem" always gives an error. the codes are below.
python code
from kivymd.app import MDApp
from kivy.core.window import Window
from kivy.lang.builder import Builder
from kivymd.uix.screenmanager import ScreenManager
from kivy.uix.boxlayout import BoxLayout
Window.size = [320, 600]
class ShopApp(MDApp):
def build(self):
global screen_manager
screen_manager = ScreenManager()
screen_manager.add_widget(Builder.load_file('home.kv'))
screen_manager.add_widget(Builder.load_file('Sign_up.kv'))
screen_manager.add_widget(Builder.load_file('login.kv'))
return screen_manager
ShopApp().run()
kv file
MDScreen:
name: 'home'
md_bg_color: 1, 1, 1, 1
background_normal: ''
MDNavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDTopAppBar:
md_bg_color: [0, 0, 0, 1]
elevation: 2.5
title: "Home"
left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
Widget:
MDNavigationDrawer:
id: nav_drawer
size_hint: .3, .9
radius: (0, 30, 30, 0)
md_bg_color: 0, 0, 0, 1
pos_hint: {'y': .1}
scrim_color: 0, 0, 0, 0
MDNavigationDrawerMenu:
MDNavigationDrawerHeader:
title: "Header title"
title_color: "#4a4939"
text: "Header text"
spacing: "4dp"
padding: "12dp", 0, 0, "56dp"
MDNavigationDrawerLabel:
text: "Mail"
DrawerClickableItem:
icon: "gmail"
right_text: "+99"
text_right_color: "#4a4939"
text: "Inbox"
DrawerClickableItem:
icon: "send"
text: "Outbox"
MDNavigationDrawerDivider:
MDNavigationDrawerLabel:
text: "Labels"
DrawerLabelItem:
icon: "information-outline"
the new class needs to be defined and inherit one that exists.
this can be done in a .kv file that you load with Builder.loadfile("filename.kv") or put this code in a .kv file that you already have. properties can be defined such as the size hint that I placed as an example.
<DrawerClickableItem#MDNavigationDrawer>:
size_hint_x: 5

Invalid indentation, must be a multiple of 8 spaces, rounded button kivy .kv file

so yeah I was learning kivy - "rounded buttons" and when I ran the tutorial's program ---------------
ERROR:
https://i.stack.imgur.com/rGhSa.png
python:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.core.window import Window
Builder.load_file("my.kv")
class MyLayout(Widget,App):
def __init__(self,*args,**kwargs):
super(MyLayout, self).__init__(**kwargs)
class AwesomeApp(App):
def build(self):
Window.clearcolor = (1,1,1,1)
return MyLayout()
if __name__ == '__main__':
AwesomeApp().run()
.kv
<MyLayout>
BoxLayout:
orientation: "vertical"
size: root.width, root.height
padding: 50
spacing: 20
Button:
text: "Hello World!"
RoundedButton:
text: "Goodbye World!"
pos_hint: {'center_x': 0.5}
size_hint: (1, .3)
#background_color: (0/255,255/255,203/255,1)
#background_normal: ''
<RoundedButton#Button>
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba: (0/255,255/255,203/255,1)
RoundedRectangle:
size: self.size
pos: self.pos
radius: [58]
thanks,can anyone help, don't like these errors,
indentation error it seems like
You are not doing proper indentation you must use only one type of indentation in a file but you are using 8 spaces and 4 spaces both as indentation that is why error is coming.
Here,I have used 4 spaces as indentation in whole code that is why its working fine.
<MyLayout>
BoxLayout:
orientation: "vertical"
size: root.width, root.height
padding: 50
spacing: 20
Button:
text: "Hello World!"
RoundedButton:
text: "Goodbye World!"
pos_hint: {'center_x': 0.5}
size_hint: (1, .3)
#background_color: (0/255,255/255,203/255,1)
#background_normal: ''
<RoundedButton#Button>
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba: (0/255,255/255,203/255,1)
RoundedRectangle:
size: self.size
pos: self.pos
radius: [58]

Kivy. Position of GridLayout inside ScrollView

I give up. I think I have tried everything I possibly could. I need some explatanion how to position nested layouts classes. In below code I need these labels to be positioned in the center of the screen. Anything I've tried leaves the Labels on the left side.
from kivy.app import App
from kivy.lang import Builder
kv = """
<StorageLabel#Label>
background_normal: ''
size_hint: None, None
size: 65, 50
canvas.before:
Color:
rgba: (1, 0, 0.5, 1)
Rectangle:
pos: self.pos
size: self.size
halign: "left"
valign: "middle"
<Storage#BoxLayout>
ScrollView:
size_hint_x: 1
bar_width: 10
scroll_type: ['bars', 'content']
bar_color: [0, 0, 0, 1]
bar_inactive_color: [0, 0, 0, 1]
pos_hint: {'center_x': 0.5}
GridLayout:
cols: 3
size_hint_y: None
size: self.minimum_size
height: self.minimum_height
StorageLabel:
text: '1m'
StorageLabel:
text: '2m'
StorageLabel:
text: '3m'
Storage:
"""
sm = Builder.load_string(kv)
class Main(App):
def build(self):
return sm
if __name__ == '__main__':
Main().run()
The easiest way to center the Labels is to let the GridLayout size and position them. This results in a larger width for each Label, but they are centered:
from kivy.app import App
from kivy.lang import Builder
kv = """
<StorageLabel#Label>
background_normal: ''
# leave size_hint_x at default of 1
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: (1, 0, 0.5, 1)
Rectangle:
pos: self.pos
size: self.size
<Storage#BoxLayout>
ScrollView:
size_hint_x: 1
bar_width: 10
scroll_type: ['bars', 'content']
bar_color: [0, 0, 0, 1]
bar_inactive_color: [0, 0, 0, 1]
pos_hint: {'center_x': 0.5}
GridLayout:
cols: 3
# add some padding and spacing
padding: 5
spacing: 5
size_hint_y: None
height: self.minimum_height
StorageLabel:
text: '1m'
StorageLabel:
text: '2m'
StorageLabel:
text: '3m'
Storage:
"""
sm = Builder.load_string(kv)
class Main(App):
def build(self):
return sm
if __name__ == '__main__':
Main().run()
If you want the labels to be your original size, then you can place each in its own Layout (perhaps a FloatLayout), and let the GridLayout size and position those Layouts:
from kivy.app import App
from kivy.lang import Builder
kv = """
<StorageLabel#Label>
background_normal: ''
size_hint: None, None
size: 65, 50
# position the label in the center of its FloatLayout
pos_hint: {'center_x':0.5}
canvas.before:
Color:
rgba: (1, 0, 0.5, 1)
Rectangle:
pos: self.pos
size: self.size
<Storage#BoxLayout>
ScrollView:
size_hint_x: 1
bar_width: 10
scroll_type: ['bars', 'content']
bar_color: [0, 0, 0, 1]
bar_inactive_color: [0, 0, 0, 1]
pos_hint: {'center_x': 0.5}
GridLayout:
cols: 3
size_hint_y: None
height: self.minimum_height
# set the default row height to the height of the Labels
row_default_height: 50
FloatLayout:
StorageLabel:
text: '1m'
FloatLayout:
StorageLabel:
text: '2m'
FloatLayout:
StorageLabel:
text: '3m'
Storage:
"""
sm = Builder.load_string(kv)
class Main(App):
def build(self):
return sm
if __name__ == '__main__':
Main().run()

Kivy: how to update a label when a button is clicked

I use a button to retrieve the paths of some folders selected with the filechooser. When the button is clicked I would like to update the text of the label so that it dispays the selected paths.
In my Kv:
Button:
text:'OK'
on_press: root.selected(filechooser.path, filechooser.selection)
Label:
id: Lb_ListViewFolder
text: root.Lb_ListViewFolder_text
color: 0, 0, 0, 1
size_hint_x: .75
In .py:
class MyWidget(BoxLayout):
Lb_ListViewFolder_text = ObjectProperty("Text")
def selected(self, a, b):
global Lb_ListViewFolder_text
Lb_ListViewFolder_text = b
print(a,b)
This doesn't give me any error but the label text isn't changed.
I also tried self.ListViewFolder.text = b like recommended here but I get this error: MyWidget' object has no attribute 'Lb_ListViewFolder'.
I have seen this answer, but I have trouble applying in my code
I use python 3.6 and Kivy 1.9.2.dev0
In case, this is my entire code:
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.event import EventDispatcher
from kivy.lang import Builder
root = Builder.load_string('''
<MyWidget>
id: BL_Main
orientation: "horizontal"
padding: 10
spacing: 10
BoxLayout:
id: BL_folder
orientation: "vertical"
Button:
id:ok
text:'OK'
background_color: 0,0,1,1
height: 5
size_hint: 0.1, 0.1
on_press: root.selected(filechooser.path, filechooser.selection)
BoxLayout:
orientation:"horizontal"
size_hint: None, 0.9
width:150
canvas.before:
Color:
rgb: .4,.5,.5
Rectangle:
pos: self.pos
size: self.size
## multiple select folder not possible with FileChooserListView
FileChooserIconView:
id: filechooser
pos:self.pos
multiselect: True
dirselect: True
Label:
id: Lb_ListViewFolder
text: root.Lb_ListViewFolder_text
color: 0, 0, 0, 1
size_hint_x: .75
''')
class MyWidget(BoxLayout):
Lb_ListViewFolder_text = ObjectProperty("Text")
def selected(self, a, b):
global Lb_ListViewFolder_text
Lb_ListViewFolder_text = b
print(a,b)
class MyApp(App):
def build(self):
Window.clearcolor = (1, 1, 1, 1)
return MyWidget()
MyApp().run()
You can use StringProperty here:
from kivy.app import App
from kivy.uix.filechooser import FileChooserListView
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import StringProperty
Builder.load_string('''
<MyLayout>:
orientation: "vertical"
Label:
text: root.label_text
Button:
id:ok
text:'OK'
on_press: root.selected(filechooser.path, filechooser.selection)
FileChooserIconView:
id: filechooser
pos:self.pos
multiselect: True
dirselect: True
''')
class MyLayout(BoxLayout):
label_text = StringProperty("File name")
def selected(self, a, b):
self.label_text = b[0]
class MyApp(App):
def build(self):
return MyLayout()
MyApp().run()
Or you can change it directly in kvlang:
<MyLayout>:
orientation: "vertical"
Label:
id: dirlabel
text: root.label_text
Button:
id:ok
text:'OK'
on_press: dirlabel.text = filechooser.selection[0]
FileChooserIconView:
id: filechooser
pos:self.pos
multiselect: True
dirselect: True

Kivy: How can I combine the two screens into one?

I am new to kivy. I have two screens and I want to combine them into one.
The code for the first screen:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.scrollview import ScrollView
from kivy.lang import Builder
Builder.load_string('''
<Button>:
font_size: 40
color: 0,1,0,1
<Widgets>:
Button:
size: root.width/2, 75
pos: root.x , root.top - self.height
text: 'OK'
Button:
size: root.width/2, 75
pos: root.x + root.width/2, root.top - self.height
text: 'Cancel'
Label:
text: "bbbbbaäa üß AäÄ"
size: root.width, 75
valign: 'middle'
halign: 'center'
anchor: 'left'
pos: root.x, root.top - 150
font_size: 50
height: 75
Label:
text: "Tssssssssssa #aaäa Äaaäa Üaa Maaäa a"
size: root.width, 75
valign: 'middle'
halign: 'left'
anchor: 'left'
pos: root.x, root.top - 150 - 50
font_size: 30
height: 50
''')
class ScrollableLabel(ScrollView):
pass
class Widgets(Widget):
def build(self):
return Widgets()
class MyApp(App):
def build(self):
return Widgets()
if __name__ == "__main__":
MyApp().run()
The code for the second screen is from Alexander Taylor: https://github.com/kivy/kivy/wiki/Scrollable-Label
I paste the code here again:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty
from kivy.lang import Builder
long_text = 'yay moo cow foo bar moo baa ' * 100
Builder.load_string('''
<ScrollableLabel>:
Label:
size_hint_y: None
height: self.texture_size[1]
text_size: self.width, None
text: root.text
''')
class ScrollableLabel(ScrollView):
text = StringProperty('')
class ScrollApp(App):
def build(self):
return ScrollableLabel(text=long_text)
if __name__ == "__main__":
ScrollApp().run()
Question one:
I want to combine those two screens into one, to have the Scrollbale Label from the second screen below the Label from the first screen. How can I do it?
Question two:
I want to have the Label text from first code started from left. Now the text is in the middle of the Label. It seems that anchor: 'left' is not working. How can I do it?
And help will be appreciated. Thanks.
You can do that like this:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.lang import Builder
from kivy.properties import StringProperty
Builder.load_string('''
<Button>:
font_size: 40
color: 0,1,0,1
<Widgets>:
GridLayout:
size_hint: 1,0.4
cols: 2
rows: 2
Button:
text: 'OK'
Button:
text: 'Cancel'
Label:
text: "bbbbb"
font_size: 50
halign: "left"
size: self.texture_size
text_size: root.width/2, None
Label:
text: "Tssssssssssa #aaäa Äaaäa Üaa Maaäa a"
font_size: 30
halign: "left"
size: self.texture_size
text_size: root.width/2, None
ScrollView:
Label:
size_hint_y: None
height: self.texture_size[1]
text_size: self.width, None
text: root.text
''')
class Widgets(BoxLayout):
text = StringProperty("")
def __init__(self,**kwargs):
super(Widgets,self).__init__(**kwargs)
self.orientation = "vertical"
self.text = 'yay moo cow foo bar moo baa ' * 100
class MyApp(App):
def build(self):
return Widgets()
if __name__ == "__main__":
MyApp().run()

Resources