I have make a simple app using kivy,kivymd and python. on_release functionality in md card not working,my code snippet below.
from kivy.lang import Builder
from kivymd.app import MDApp
kv = '''
Screen:
MDCard:
size_hint: None, None
size: "280dp", "180dp"
pos_hint: {"center_x": .5, "center_y": .5}
ripple_behavior: True
on_release:print("worked")
'''
class TestCard(MDApp):
def build(self):
return Builder.load_string(kv)
TestCard().run()
You have to be careful with the tabs you use in your kv string. First of all you start with a tab before the Screen declaration. Thats not working. Then you have to set tabs after you declare the MDCard to set its attributes. Like this it works for me:
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
Screen:
MDCard:
size_hint: None, None
size: "280dp", "180dp"
pos_hint: {"center_x": .5, "center_y": .5}
ripple_behavior: True
on_release: print("worked")
'''
class TestCard(MDApp):
def build(self):
return Builder.load_string(KV)
TestCard().run()
The problem with your code is python statements don't work in .kv files. Another problem is the indentation. So, just change the indentation and create a method in your TestCard class like this :
from kivy.lang import Builder
from kivymd.app import MDApp
kv = '''
Screen:
MDCard:
size_hint: None, None
size: "280dp", "180dp"
pos_hint: {"center_x": .5, "center_y": .5}
ripple_behavior: True
on_release: app.work()
'''
class TestCard(MDApp):
def build(self):
return Builder.load_string(kv)
def work(self):
print("worked")
TestCard().run()
Related
I followed a tutorial on youtube so I could learn how to use kivy, but when I try to switch screen it doesn't work, I write my code the exact same way the guy does it, but for some reason nothing happens when I click the button "Se dine produkter".
I have written where I need help in the .kv file, I added the rest of the code only in case if you need to know why I have done certain things. In line 10 and 25 I have written what I want to happen, I have tried so many different things and different ways to approach what I want, but I haven't succeed with any of them.
main.py:
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_file("struktur.kv")
class HovedVindu(Screen and Widget):
def nyttProdukt(self):
show_popup()
def dineProdukter(self):
print("dine produkter")
ScreenManager.current = "dineprodukter"
def leggTilNyttProdukt(self, navn, dato):
self.navn = navn
self.dato = dato
print(self.navn, self.dato)
class DineProdukter(Screen):
pass
class WindowManager(ScreenManager):
pass
class P(FloatLayout):
pass
class MainApp(App):
def build(self):
return HovedVindu()
def show_popup():
show = P()
popupWindow = Popup(title="Legg til ett nytt produkt", content=show, size_hint=(None,None),size=(400,400), title_align="center")
popupWindow.open()
if __name__ == "__main__":
MainApp().run()
struktur.kv:
#:kivy 2.1.0
<WindowManager>:
HovedVindu:
DineProdukter:
<DineProdukter>:
name: "dineprodukter"
Button:
text: "Go to main"
on_release: switch to (hoved)
<HovedVindu>:
name: "hoved"
FloatLayout:
Button:
text: "Nytt produkt"
size_hint: 2, 1
pos_hint: {"x": 3, "top": 5}
on_release: root.nyttProdukt()
Button:
text: "Se dine produkter"
size_hint: 2, 1
pos_hint: {"x": 3, "top": 3}
on_release: switch to (dineprodukter)
<P>:
TextInput:
hint_text: "Navnet på produktet"
size_hint: .6, .15
pos_hint: {"x": .2, "top": .9}
TextInput:
hint_text: "Siste forbruksdag"
size_hint: .6, .15
pos_hint: {"x": .2, "top": .7}
Button:
text: "Legg til produkt"
size_hint: 0.8, 0.2
pos_hint: {"x":0.1, "y":0.1}
It happens because you are actually not using Screen Manager.
Please follow official kivy documentation on how to use ScreenManager.
https://kivy.org/doc/stable/api-kivy.uix.screenmanager.html
Example code of build function using ScreenManager:
def build(self) -> ScreenManager:
self.sm = ScreenManager()
self.sm.add_widget(SplashScreen(name='splash_screen'))
self.sm.add_widget(DownloadScreen(name='download_screen'))
self.sm.add_widget(InfoScreen(name='info_screen'))
self.sm.add_widget(FileManager(name='file_manager'))
return self.sm
Example usage in .kv file:
MDFillRoundFlatIconButton:
text: 'Download'
icon: 'download'
pos_hint: {'x': 0.77, 'y': 0.01}
md_bg_color: 64/255, 120/255, 192/255, 1
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'download_screen'
There is some other ways to do it, but I don't think your code is exactly the same as the code of the guy from YouTube. Stick to kivy documentation, it is actually good and you will learn 'kivy ways' of doing things.
Using switch_to(screen_name) not switch to(screen_name) won't work either if you won't use instance of your Screen Manager. Without that is just non existing function.
Here please you have your code fixed up a bit:
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_file("struktur.kv")
class HovedVindu(Screen):
def nyttProdukt(self):
show_popup()
def dineProdukter(self):
print("dine produkter")
ScreenManager.current = "dineprodukter"
def leggTilNyttProdukt(self, navn, dato):
self.navn = navn
self.dato = dato
print(self.navn, self.dato)
class DineProdukter(Screen):
pass
class P(FloatLayout):
pass
class MainApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(HovedVindu(name="hoved"))
sm.add_widget(DineProdukter(name="dineprodukter"))
return sm
def show_popup():
show = P()
popupWindow = Popup(title="Legg til ett nytt produkt", content=show, size_hint=(None,None),size=(400,400), title_align="center")
popupWindow.open()
if __name__ == "__main__":
MainApp().run()
And kivy file:
#:kivy 2.1.0
<DineProdukter>:
FloatLayout:
Button:
text: "Go to main"
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: .2, .2
on_release: root.manager.current = "hoved"
<HovedVindu>:
FloatLayout:
Button:
text: "Nytt produkt"
size_hint: .3, .1
pos_hint: {"x": .7, "y": .5}
on_release: root.nyttProdukt()
Button:
text: "Se dine produkter"
size_hint: .3, .1
pos_hint: {"x": .3, "y": .5}
on_release: root.manager.current = "dineprodukter"
<P>:
TextInput:
hint_text: "Navnet på produktet"
size_hint: .6, .15
pos_hint: {"x": .2, "top": .9}
TextInput:
hint_text: "Siste forbruksdag"
size_hint: .6, .15
pos_hint: {"x": .2, "top": .7}
Button:
text: "Legg til produkt"
size_hint: 0.8, 0.2
pos_hint: {"x":0.1, "y":0.1}
Haven't done everything but it displays screens and buttons do work.
I have kicked out your class of ScreenManager and actually created an instance of it in the root of your app. That way you can call it from any screen, as they are added to the Manager. Like you need to give screens to the Manager before it can manage it. That way always works fine and you won't experience any problems even if your app will contain 20 or more different classes with screens.
Hi I was wondering how to make a dropdown menu and I cant figure it out I have read the documentation but I do not understand so I would be grateful if someone told my the problem with my attempt at is in my code.
PYTHON FILE:
from kivymd.app import MDApp
from kivymd.uix.screen import Screen
from kivymd.uix.button import MDRectangleFlatButton, MDRoundFlatButton
from kivymd.uix.textfield import MDTextField
from kivy.lang import Builder
from kivymd.uix.menu import MDDropdownMenu
from kivy.metrics import dp
from kivy.properties import StringProperty
from kivymd.uix.list import OneLineIconListItem
class IconListItem(OneLineIconListItem):
icon = StringProperty()
class DemoApp(MDApp):
def show_data(self):
inputFahrenheit = self.root.ids.fahrenheit.text
print(inputFahrenheit)
def fahrenheitSelected(self):
fahrenheit = True
celsius = False
def on_start(self):
self.theme_cls.primary_palette = "Green"
self.theme_cls.primary_hue = "A700"
self.theme_cls.theme_style = "Light"
self.dropdown1 = MDDropdownMenu()
self.dropdown1.items.append(
{"viewclass": "MDMenuItem",
"text": "option1",
"callback": self.callback()}
)
def callback(self):
print("cookies")
def build(self):
kv = Builder.load_file("test.kv")
screen = Screen()
return kv
DemoApp().run()
KV FILE:
Screen:
MDTextField:
id: fahrenheit
hint_text:"Enter Fahrenheit"
helper_text: "Once you enter the fahrenheit the press submit"
helper_text_mode: "on_focus"
icon_right: "temperature-fahrenheit"
pos_hint: {'center_x': 0.5, 'center_y': 0.9}
size: 200, 25
size_hint: None, None
MDRoundFlatButton:
text: "Enter"
pos_hint: {'center_x': 0.5, 'center_y': 0.2}
text_color: 0, 1, 0, 1
size_hint: 0.25, 0.20
on_release: app.show_data()
MDIconButton:
icon: "language-python"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.dropdown.open(root)
I don't know what is going on hear so I would appreciate it if someone knew the answer and posted it here.
I do not know what this class is - "MDMenuItem", you did not present it in your example, but as I understood you want to use it in the list menu, so I specified OneLineListItem as a viewclass, the list does not have a callback method (and in general it does not exist in almost all kivy classes), instead you should use on_release or on_press as in my example. If you do not want to use lambda, then you do not need to explicitly call the function - "on_release": self. callback. Also, to access some object of the class (in your example, it is MDDropdownMenu), it must be defined in __init__. Also, menu_items should be a list, not a dictionary as in your example, read the documentation carefully. You also forgot to specify the caller argument of the MDDropdownMenu class. I also noticed that you have the IconListItem class, but you don't use it anywhere, so I deleted it, if you want to create a list with icons, see this. And you should not specify the definition of the theme and color in the examples, this does not affect anything.
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
from kivy.properties import StringProperty
from kivy.lang import Builder
KV = """
Screen:
MDTextField:
id: fahrenheit
hint_text:"Enter Fahrenheit"
helper_text: "Once you enter the fahrenheit the press submit"
helper_text_mode: "on_focus"
icon_right: "temperature-fahrenheit"
pos_hint: {'center_x': 0.5, 'center_y': 0.9}
size: 200, 25
size_hint: None, None
MDRoundFlatButton:
text: "Enter"
pos_hint: {'center': (0.5,0.2)}
text_color: 0, 1, 0, 1
size_hint: 0.25, 0.20
on_release: app.show_data()
MDIconButton:
id: button
icon: "language-python"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.dropdown1.open()
"""
class DemoApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_string(KV)
menu_items = [
{
"viewclass": "OneLineListItem",
"text": "Option1",
"on_release": lambda *args: self.callback()
}
]
self.dropdown1 = MDDropdownMenu(items=menu_items, width_mult=4, caller=self.screen.ids.button)
def build(self):
return self.screen
def show_data(self):
input_fahrenheit = self.root.ids.fahrenheit.text
print(input_fahrenheit)
#staticmethod
def callback():
print("cookies")
DemoApp().run()
Why can I move the button only horizontally using the vertical orientation of BoxLayout, and only vertically using the horizontal orientation? For example:
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
Screen:
BoxLayout:
orientation: 'vertical'
MDRaisedButton:
pos_hint: {'center_x': .3,'center_y': .5}
'''
class Test(MDApp):
def build(self):
return Builder.load_string(KV)
Test().run()
Horizontal orientation, also the default orientation:
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
Screen:
BoxLayout:
orientation: 'horizontal'
MDRaisedButton:
pos_hint: {'center_x': .3,'center_y': .5}
'''
class FindWord(MDApp):
def build(self):
return Builder.load_string(KV)
FindWord().run()
How to move widgets freely on both axes? Help please
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
MDBoxLayout:
adaptive_size: True
pos_hint: {'center_x': .3, 'center_y': .5}
MDRaisedButton:
text: "MDRaisedButton"
'''
class FindWord(MDApp):
def build(self):
return Builder.load_string(KV)
FindWord().run()
https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html
I want that on pressing enter in a TextInput widget it should do two things-
change the screen (i am using screen manager)
and search for the keyword
I do know that with on_text_validate we can perform either of the tasks by-
1.root.manager.current='namesomething'
2.root.function_which_has_search_algorithm()
is there anyway with which i can do both the things(changing_the_screen,calling_the_search_function) using on_text_validate or do i have to use some other technique?
here a sample code:
import kivy
kivy.require("1.10.0")
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
Builder.load_file('screenswitch.kv')
class MainScreen(Screen):
def SelectWord(self):
''' some search
code'''
class OtherScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(OtherScreen(name='other'))
class ScreenSwitchApp(App):
def build(self):
return sm
obj = ScreenSwitchApp()
obj.run()
heres my kivy code:
<MainScreen>:
BoxLayout:
TextInput:
text: "Search your word here"
color: 1,1,1,1
id: search_input
width: 200
size_hint: None, .20
pos_hint: {"center_x": .5, "center_y": 0.5}
multiline: False
on_text_validate: root.SelectWord() # i want this to change screen also
<OtherScreen>:
BoxLayout:
Button:
text: 'back to main screen'
on_press: root.manager.current='main'
A possible solution is to create a new function that calls that 2 functions:
*.py
import kivy
kivy.require("1.10.0")
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
Builder.load_file('screenswitch.kv')
class MainScreen(Screen):
def some_function(self):
self.SelectWord()
self.manager.current='other'
def SelectWord(self):
print("SelectWord")
class OtherScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(OtherScreen(name='other'))
class ScreenSwitchApp(App):
def build(self):
return sm
obj = ScreenSwitchApp()
obj.run()
*.kv
<MainScreen>:
BoxLayout:
TextInput:
text: "Search your word here"
color: 1,1,1,1
id: search_input
width: 200
size_hint: None, .20
pos_hint: {"center_x": .5, "center_y": 0.5}
multiline: False
on_text_validate: root.some_function() # i want this to change screen also
<OtherScreen>:
BoxLayout:
Button:
text: 'back to main screen'
on_press: root.manager.current='main'
TextInput:
id:qty_inp
size_hint_x:.1
multiline:False
on_text_validate:root.update_price()
on_text_validate:root.update_purchase
Like the above code you can add one more on_text_validate: root.method()
There is something in kivy I do not understand, and am hoping that someone could shed light. I have done a lot of reading in this topic but it just doesn't seem to be connecting in my head.
My issue comes from linking a function to a kivy button.
Right now I am trying to learn how to do a simple function:
def Math():
print 1+1
What I would like to do something more complex:
def Math(a,b):
print a^2 + b^2
Where a and b are input labels from kivy, and upon clicking a button the answer will be printed.
This is what I have so far:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
#######``Logics``#######
class Math(FloatLayout):
def add(self):
print 1+1
#######``Windows``#######
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("GUI_Style.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == "__main__":
MainApp().run()
This is my kivy language file:
import NoTransition kivy.uix.screenmanager.NoTransition
ScreenManagement:
transition: NoTransition()
MainScreen:
AnotherScreen:
<MainScreen>:
name: "main"
FloatLayout:
Button:
on_release: app.root.current = "other"
text: "Next Screen"
font_size: 50
color: 0,1,0,1
font_size: 25
size_hint: 0.3,0.2
pos_hint: {"right":1, "top":1}
<AnotherScreen>:
name: "other"
FloatLayout:
Button:
color: 0,1,0,1
font_size: 25
size_hint: 0.3,0.2
text: "add"
pos_hint: {"x":0, "y":0}
on_release: root.add
Button:
color: 0,1,0,1
font_size: 25
size_hint: 0.3,0.2
text: "Back Home"
on_release: app.root.current = "main"
pos_hint: {"right":1, "top":1}
<AnotherScreen>:
name: "other"
FloatLayout:
Button:
...
on_release: root.add <-- here *root* evaluates to the top widget in the rule.
Which is an AnotherScreen instance, but it doesn't have an add method.
class Math(FloatLayout):
def add(self):
print 1+1
Here you have declared a Math class by inheriting from the FloatLayout, which is a uix component -a widget-. And you defined a method on this class add. Still you haven't used it. In the kv file you used FloatLayout.
Now in order for you to access a function in kv, most of the time you'll acces it as a method of a uix component, by using either root/self or app, you can also import it e.g:
#: import get_color_from_hex kivy.utils.get_color_from_hex
<ColoredWidget>:
canvas:
Color:
rgba: get_color_from_hex("DCDCDC")
Rectangle:
size: self.size
pos: self.pos
So you can't do it like this:
<AnotherScreen>:
name: "other"
Math:
id: math_layout
Button:
...
on_release: math_layout.add()
or like this:
class AnotherScreen(Screen):
def add(self):
print(1+1)
If you still have problems conserning this topic, i'll be glad to provide more help .