How to make round edges in a MDCard KivyMD - python

I am doing an App in kivy using kivyMD but I Want to insert a MDcard, the thing is that I want the MDCard look like this:
But it looks like this:
I know it can be with border_radius but I dont know how to do it,
here is my code:
PY:
import kivy
from kivymd.app import MDApp
from kivymd.uix.card import MDCard
class Home(MDCard):
pass
class Manage(MDApp):
title = 'QUICKP'
def build(self):
return Home()
if __name__ == '__main__':
Manage().run()
KV:
<Home>
MDCard:
size_hint: None, None
size: "280dp", "180dp"
pos_hint: {"center_x": .5, "center_y": .5}

You do not need to modify the card.py file nor do you have to use canvas you just have to place the following in your kivy code
border_radius: 20
radius: [15]
In border_radius you put the border limit that you will be able to use and in radius you put the border level that your mdcard will have.

People advise to use canvas its OK, but it increase your coding and make it very complex. Just go to the Kivymd>uix>card.py line 631 change the default from 3dp to for example 20dp or whatever you want. then go back to your code and type radius: [] and insert your desire number from 20 to 0.
Done!!!

#BernardoOlisan You can use this directly
MDCard:
size_hint: None, None
size: "280dp", "180dp"
pos_hint: {"center_x": .5, "center_y": .5}
elevation: 15
radius: 10
MDLabel:
text: 'Your title'
halign: 'center'
pos_hint: {"center_x": .5, "center_y": .5}
It works for sure

I had the same problem, and there is a border_radius property for MDCards, but it does not work. But i have solved this with this code:
<MyCard>:
orientation: 'vertical'
size_hint: 0.1, 1
canvas.before:
Color:
rgba: app.theme_cls.primary_color
RoundedRectangle:
radius: [10]
size: self.size
pos: self.pos
FloatLayout:
size: self.size
pos: self.pos
pos_hint: {"x": -0.1, "y": -0.6}
And here is a part from .py file:
class Plan(RectangularElevationBehavior, RectangularRippleBehavior, FloatLayout):
ripple_scale = 1.4
text = StringProperty()
text_label = StringProperty()
So, it creates a MyCard(FloatLayout class) with Canvas in it, which inherits from FloatLayout, RippleBehaviour and ElevationBehaviour. And then you can add to that FloatLayout in it to manage content of it. But if it looks strange because of the position, try playing with pos_hint-s.

Related

Carousel and self.root code problem. I am developing an Application using Python Kivy. My code closes after clicking the button

The code closes after clicking the first proceed when it is supposed to continue to the next page and can click the procceed button again, it should 4 times after clicking the Proceed button again. When I tried not to compile the code with other kivy files, it runs very well and accurate but when I try to compiled it again, it closes right away after clicking the Proceed button, the carousel itself is working but also in only one slide. It's not continue going to the next page. I have try to add and change the code but it shows the same error. Can someone please help me.
Here is the entire code fot python file:
from kivy.clock import Clock
from kivy.uix.gridlayout import GridLayout
from kivymd.uix.widget import Widget
from kivy.core.window import Window
from kivy.utils import rgba
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.text import LabelBase
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.scrollview import ScrollView
Window.size = (310, 580)\`
class Scrolling(ScrollView):
pass
class OnBoarding(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
global screen_manager
screen_manager = ScreenManager()
screen_manager.add_widget(Builder.load_file("one.kv"))
screen_manager.add_widget(Builder.load_file("two.kv"))
screen_manager.add_widget(Builder.load_file("three.kv"))
self.root = Builder.load_file("main.kv")
self.theme_cls.primary_palette = "Green"
self.theme_cls.theme_style = "Light"
return screen_manager
def on_start(self):
Clock.schedule_once(self.change_screen, 5)
def change_screen(self,dt):
screen_manager.current = "two"
def current_slide(self, index):
for i in range(4):
if index != i:
self.root.ids[f"slide{i}"].color = rgba(131, 173, 97)
else:
self.root.ids[f"slide{i}"].color = rgba(79, 121, 47)
def next(self):
self.root.ids.carousel.load_next(mode="next")
if __name__ == '__main__':
OnBoarding().run()
Here is the kv file:
MDScreen:
name:"main"
MDFloatLayout:
md_bg_color:1, 1, 1, 1
Image:
source:"background.png"
size_hint: .7, .7
pos_hint: {"center_x": .5, "center_y": .65}
MDFloatLayout:
id: parent_widget
md_bg_color:1, 1, 1, 1
Carousel:
id: carousel
on_current_slide: app.current_slide(self.index)
MDFloatLayout:
Image:
source:"first.png"
size_hint: .8, .9
pos_hint: {"center_x": .5, "center_y": .70}
MDLabel:
text: "First Page"
font_size: "20sp"
pos_hint: {"center_y": .45}
color: rgba(34, 34, 34, 255)
MDLabel:
text: "First Definition"
pos_hint: {"center_x": .5, "center_y": .37}
size_hint_x: .85
color: rgba(34, 34, 34, 255)
MDFloatLayout:
Image:
source:"second.png"
size_hint: .8, .8
pos_hint: {"center_x": .5, "center_y": .70}
MDLabel:
text: "Second Page"
pos_hint: {"center_y": .45}
halign: "center"
color: rgba(34, 34, 34, 255)
MDLabel:
text: "Second Definition"
pos_hint: {"center_x": .5, "center_y": .37}
size_hint_x: .85
color: rgba(34, 34, 34, 255)
Button:
text: "Proceed"
background_color: 0, 0, 0, 0
font_size: "18sp"
size_hint: .8, .070
pos_hint: {"center_x": .5, "center_y": .2}
border: 0, 32, 0, 32
canvas.before:
Color:
rgb: rgba(79, 121, 47)
RoundedRectangle:
size: self.size
pos: self.pos
radius: [20]
on_release:
app.next()
MDLabel:
id: slide0
text: "."
halign: "center"
font_size: "80sp"
color: rgba(79, 121, 47)
pos_hint: {"center_x": .40, "center_y": .31}
MDLabel:
id: slide1
text: "."
halign: "center"
font_size: "80sp"
color: rgba(131,173,97)
pos_hint: {"center_x": .47, "center_y": .31}
MDLabel:
id: slide2
text: "."
halign: "center"
font_size: "80sp"
color: rgba(131,173,97)
pos_hint: {"center_x": .55, "center_y": .31}
The code closes after clicking the first proceed when it is supposed to continue to the next page and can click the procceed button again, it should 4 times after clicking the Proceed button again. When I tried not to compile the code with other kivy files, it runs very well and accurate but when I try to compiled it again, it closes right away after clicking the Proceed button, the carousel itself is working but also in only one slide. It's not continue going to the next page. I have try to add and change the code but it shows the same error. Can someone please help me.
You did not add Builder.load_file("main.kv") to ScreenManager object. Replace self.root = Builder.load_file("main.kv") with screen_manager.add_widget(Builder.load_file("main.kv"))
You did not provided one.kv, two.kv and three.kv content
Replace all occurences of self.root.ids with self.root.get_screen('main').ids
You don't have any Screen with name "two" specified within change_screen method which is invoked after 5 seconds from start.
You are trying to set color attribute within loop for i in range(4): for ids[slide3] ids[f"slide{i}"] while there is no widget with id: slide3 within your main.kv
Fix your code, and post console output if you want to get quality help.

Kivy change slider design

Is it possible to make a kivy slider look like this one?
This is my python code:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
class MyWidget(GridLayout):
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
Window.clearcolor = (1, 1, 1, 1)
class PhoneApp(App):
def build(self):
return MyWidget()
if __name__ == "__main__":
PhoneApp().run()
This is my kv code:
#:kivy 2.1.0
<Label>
size_hint_y: None
height: self.texture_size[1]
color: 0, 0, 0, 1
<Image>
size_hint_y: None
height: self.texture_size[1]
<Button>
size_hint_x: None
size_hint_y: None
width: self.texture_size[0]
height: self.texture_size[1]
<Slider>
size_hint_y: None
<GridLayout>
cols: 1
size_hint: (0.5, 0.9)
pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyWidget>:
Image:
source: "captus.png"
Label:
text: "Test Message"
Button:
text: "Second test"
Slider:
id: slider
min: 0
max: 100
For now the slider looks like this:
Is it possible to make it look like the first one?
Also.. I'm wrong or it's like bugged, not aligned with the bar?
First of all, you generally should not create dynamic classes with their default class names as it may affect its overall design for all of its instances which you may not want. Rather create an instance of that class and apply your design or logic therein. So you should change the lines like <Button> in kvlang with <MyButton#Button>.
Now since here you're using the GridLayout as a container you have fewer control over its children's attributes like pos etc. The Slider is also a widget, so you can adjust its size. To change its appearance you can use its properties like cursor_image etc. With all these changes your code in kvlang should now look something like the following,
#:kivy 2.1.0
<MyLabel#Label>
size_hint_y: None
height: self.texture_size[1]
color: 0, 0, 0, 1
<MyImage#Image>
size_hint_y: None
height: self.texture_size[1]
<MyButton#Button>
# size_hint_x: None
size_hint_y: None
# width: self.texture_size[0]
height: self.texture_size[1]
<MySlider#Slider>
size_hint_y: None
height: dp(64) # Set specific height.
cursor_image: "path to image"
background_horizontal: "some path to image"
#<MyGridLayout#GridLayout>
# cols: 1
# size_hint: (0.5, 0.9)
# pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyWidget>:
cols: 1
size_hint: (0.5, 0.9)
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MyImage:
keep_ratio: True
source: "captus.png"
MyLabel:
text: "Test Message"
MyButton:
text: "Second test"
MySlider:
id: slider
min: 0
max: 100

Adaptive_width property of MDLabel is not working correctly

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

Kivy - Referencing IDs of Subclasses (Nested IDs)

I'm creating a kivy app right now. I'm quite new to Kivy and kv lang and there doesn't seam to be much rumour about it although i find it great to seperate code logic and layout, especially after some pygame development.
So to my actuall problem: I have a wiki-style screen for screenmanager, consisting out of a BoxLayout:
Title as Label
Scrollable Label for the Text (later , there shall be displayed a nested kv file)
Buttons for Navigation (scroll up and go back to main screen)
Now I'm recreating the Navigation buttons to be floating type as known from many webpages and apps. Problem is, I suddendly cant reference my ScrollView anymore. Any help or suggestions?
<Wiki>:
name: "wiki"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: "picture.jpg"
BoxLayout:
id: box
orientation: "vertical"
padding: 10
spacing: 10
Label:
font_size: 20
size_hint_y: .1
text: root.country_text
ScrollView:
id: scrlvw
BackgroundLabel:
background_color: 220,220,220, 0.5
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
halign: "left"
valign: "top"
text: root.wiki_text
FloatLayout:
size_hint_y: .1
Button:
size_hint_x: .2
pos_hint: {"center_x": .25, "center_y": .5}
text: "Back"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
FloatButton:
size_hint_x: .2
pos_hint: {"center_x": .75, "center_y": .5}
text: "Up"
on_release:
widget = BoxLayout()
widget.ids.scrlvw.scroll_y = 0
Before, when it worked, it was:
BoxLayout:
FloatLayout:
size_hint_y: .1
Button:
size_hint_x: .2
pos_hint: {"center_x": .25, "center_y": .5}
text: "Back"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
Button:
size_hint_x: .2
pos_hint: {"center_x": .75, "center_y": .5}
text: "Up"
on_release:
scrlvw.scroll_y = 0
Well as its just a design question, I guess i temporary have to dismiss the floating design. But I would be so pleased if you could help me understand this language better.
As long as the 'kv' code described as "when it worked" is still in the same <Wiki> rule, it should still work. The newer kv code will never work as you are trying to create a new BoxLayout and reference an id in it. That has two problems:
The newly created BoxLayout is not the BoxLayout instance that appears in your GUI, so any changes to it will have no effect on what appears in the display.
Unless you have a <BoxLayout> rule in your kv, the newly created BoxLayout will not have a scrlvw id.
The ids defined within a kv rule are available for use only within that rule. See the documntation.

Updating Kivy Label Using Threading

I am trying to make a Kivy label that shows a string that is just a list of names. My end goal is to make it so you can add or remove to the list of names and the label will indicate the names on the list. As of now I have a label and a function in my .py file that compiles the list of names into a string.
Each name in the string is separated by a "\n". My problem however, is that the label does not update and show the names even though the function returns the names. I researched this problem and heard about threading. However, I do not understand how to use it in my case and am asking for some guidance.
Below is my code:
kv CODE:
<SettingsWindow>:
name:"settings"
FloatLayout:
Widget:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: "Images/logo_br.png"
Color:
rgba: 0,0,0,.5
Rectangle:
size: 200, 330
pos: self.width/10, self.height/4
Button:
text:"Back"
size_hint: 0.1, 0.1
pos_hint: {"x":0, "y":0}
background_color: 1,1,1,.6
on_release:
app.root.current = "main"
root.manager.transition.direction = 'right'
Label:
text: root.pretty_list_people
size: self.texture_size
pos_hint: {"x":0.35, "y":-0.46}
color: 1,1,1,1
Button:
text:"Show Bros"
size_hint: 0.3, 0.3
pos_hint: {"x":0.3, "y":0.1}
on_press: root.Pretty_Print_People(root.get_str_People())
py CODE:
class SettingsWindow(Screen):
pretty_list_people = ""
def get_str_Jobs(self):
return WindowManager.jobs
def get_str_People(self):
return WindowManager.people
def Pretty_Print_People(self, ppl_list):
for person in ppl_list:
self.pretty_list_people += person + "\n"
class HelpWindow(Screen):
pass
class WindowManager(ScreenManager):
jobs = ["Scrub", "Wash", "Clean"]
people = ["Anthony", "Tim", "John"]
job_assignments = {}
I tried to show only the necessary code.
This should work, uses kivy properties:
Change:
pretty_list_people = ""
To:
pretty_list_people = StringProperty ("")
And add the import:
from kivy.properties import StringProperty
At the start of your program
Hope this helps you to solve your problem

Categories

Resources