I'm working on a kivy project. I have tested the kivymd navigation layout. I wonder how can I update the label in screen 1 and screen 2. eg, count from 1 to 100 when start button is pressed.
I have searched online about kivy update label like this:
update label
but the in kv string the screen is in "< >", while mine is "Screen:", and I have tried to create a function called Screen() but it is not wokring.
Can anyone please explain to me what does "< >" mean and how can I dynamically update the label in the kivymd navigation layout? thank you very much
code is here:
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
KV = '''
<ContentNavigationDrawer>:
<ItemDrawer>:
theme_text_color: "Custom"
on_release: self.parent.set_color_item(self)
IconLeftWidget:
id: icon
icon: root.icon
theme_text_color: "Custom"
text_color: root.text_color
<ContentNavigationDrawer>:
orientation: "vertical"
padding: "8dp"
spacing: "8dp"
AnchorLayout:
anchor_x: "left"
size_hint_y: None
height: avatar.height
Image:
id: avatar
size_hint: None, None
size: "56dp", "56dp"
source: "data/logo/kivy-icon-256.png"
MDLabel:
text: "KivyMD library"
font_style: "Button"
size_hint_y: None
height: self.texture_size[1]
MDLabel:
text: "kivydevelopment#gmail.com"
font_style: "Caption"
size_hint_y: None
height: self.texture_size[1]
ScrollView:
MDList:
OneLineListItem:
text: "Screen 1"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 1"
OneLineListItem:
text: "Screen 2"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 2"
Screen:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "MDNavigationDrawer"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
NavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
Screen:
name: "scr 1"
MDLabel:
text: "Screen 1"
halign: "center"
Screen:
name: "scr 2"
MDLabel:
text: "Screen 2"
halign: "center"
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
'''
class ContentNavigationDrawer(BoxLayout):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
class TestNavigationDrawer(MDApp):
def build(self):
return Builder.load_string(KV)
TestNavigationDrawer().run()
You can try with app.root.get_screen('scr1').funct() and make a function to change what you want
Related
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.
I'm quite new to Python and Kivy.
I'm Building an app for Android.
I'm using a modifyed version of the Navigation Drawer example from here: https://kivymd.readthedocs.io/en/latest/components/navigationdrawer/
I want to get the Value of the Textfield from scr 1 vorname_input. I get this before without switchable screens. But i can't figure out how it works with the different screens. I googled for several hours and tryed so much things but i can't get it working.
If I use print (self.root.ids.vorname_input.text) its empty.
KV File:
<ContentNavigationDrawer>
MDList:
OneLineListItem:
text: "Screen 1"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 1"
OneLineListItem:
text: "Screen 2"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 2"
MDScreen:
MDTopAppBar:
pos_hint: {"top": 1}
elevation: 4
title: "MDNavigationDrawer"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
MDNavigationLayout:
MDScreenManager:
id: screen_manager
MDScreen:
name: "scr 1"
BoxLayout:
orientation: "vertical"
#size: root.width, root.height
spacing: "25dp"
padding: [12, 80, 12, 12]
MDTextField:
id: vorname_input
hint_text: "Vorname"
mode: "rectangle"
multiline: False
icon_left: 'account'
helper_text_mode: 'on_error'
helper_text: ''
mode: "fill"
fill_color: 0, 0, 0, .4
MDFlatButton:
#size_hint: (1, .5)
font_size: 25
text: "Kunde Speichern"
on_press: app.save_cust_to_db()
md_bg_color: app.theme_cls.primary_color
theme_text_color: "Custom"
text_color: 0.93, 0.93, 0.93, 1
MDScreen:
name: "scr 2"
MDLabel:
text: "Screen 2"
halign: "center"
MDNavigationDrawer:
id: nav_drawer
radius: (0, 16, 16, 0)
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
Py File:
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from kivymd.uix.scrollview import MDScrollView
class ContentNavigationDrawer(MDScrollView):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
class Example(MDApp):
def build(self):
self.theme_cls.primary_palette = "Orange"
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
def save_cust_to_db(self):
print (self.root.ids.vorname_input.text)
Example().run()
I found my mistake. In the KV file downwards i had another label with the same id. So it gets always overwritten and printet nothing because this textinputfield was empty.
It was a common copy and paste misstake :)
I´m trying to figure out, how to get the selected date from my Datepicker into a Label in the kv file. Maybe someone can help me. Greetings
The code from py file
from tkinter import Button
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd.uix.picker import MDDatePicker
from datetime import datetime
from kivy.properties import StringProperty
class Demo(ScreenManager):
pass
class Main(MDApp):
def build(self):
Builder.load_file("layout.kv")
return Demo()
def on_save(self, instance, value, date_range):
print(instance, value, date_range)
fristbeginn = StringProperty(value)
def on_cancel(self, instance, value):
'''Events called when the "CANCEL" dialog box button is clicked.'''
def show_date_picker(self):
date_dialog = MDDatePicker()
date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel)
date_dialog.open()
#class DatePicker(Button):
class Content(BoxLayout):
nav_drawer = ObjectProperty()
manager = ObjectProperty()
Main().run()
The code from .kv file:
<Content>:
ScrollView:
MDList:
OneLineListItem:
text: "Screen 1"
on_release:
root.nav_drawer.set_state("close")
root.manager.current = "screen1"
OneLineListItem:
text: "Screen 2"
on_release:
root.nav_drawer.set_state("close")
root.manager.current = "screen2"
OneLineListItem:
text: "Screen 3"
on_release:
root.nav_drawer.set_state("close")
root.manager.current = "screen3"
OneLineListItem:
text: "Screen 4"
on_release:
root.nav_drawer.set_state("close")
root.manager.current = "screen4"
OneLineListItem:
text: "Screen 5"
on_release:
root.nav_drawer.set_state("close")
root.manager.current = "screen5"
<Demo>:
Screen:
adaptive_size: True
MDToolbar:
pos_hint: {"top":1}
title: "Menü"
elevation: 8
left_action_items:[["menu", lambda x: nav_drawer.set_state("open") ]]
MDNavigationDrawer:
id: nav_drawer
Content:
nav_drawer: nav_drawer
manager: screen_manager
MDNavigationLayout:
ScreenManager:
id: screen_manager
Screen:
name: "screen1"
MDLabel:
text: "Guten Tag Bildschirm 1"
halign: "center"
Screen:
name: "screen2"
MDBoxLayout:
adaptive_size: True
size_hint: .8, None
orientation: "vertical"
pos_hint: {'center_x': .7, 'center_y': 0.55}
spacing: '20dp'
padding: ('20dp', '20dp', '20dp', '20dp')
MDLabel:
text: "Berechnung einer Frist nach §183 BGB:"
halign: "left"
font_style: "Subtitle1"
#pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDLabel:
text:""
halign: "center"
MDLabel:
text: "Wählen sie den Tag des Fristbeginn aus"
halign: "left"
font_style: "Subtitle2"
MDRaisedButton:
text: "Datum wählen"
on_release:app.show_date_picker()
MDLabel:
id: fristbeginn
text: root.fristbeginn
halign: "left"
font_style: "Subtitle2"
MDRaisedButton:
text: "MDRaised Button"
MDRaisedButton:
text: "MDRaised Button"
MDRaisedButton:
text: "MDRaised Button"
MDRaisedButton:
text: "MDRaised Button"
MDRaisedButton:
text: "MDRaised Button"
Screen:
name: "screen3"
MDLabel:
text: "Guten Tag Bildschirm 3"
halign: "center"
Screen:
name: "screen4"
MDLabel:
text: "Guten Tag Bildschirm 4"
halign: "center"
Screen:
name: "screen5"
MDLabel:
text: "Guten Tag Bildschirm 5"
halign: "center"
You are close. Using a StringProperty is a good idea, but you must define a StringProperty inside a class, but not within a method. Since your kv references root.fristbeginn, that property must be in the Demo class, like this:
class Demo(ScreenManager):
fristbeginn = StringProperty()
And the on_save() method becomes:
def on_save(self, instance, value, date_range):
print(instance, value, date_range)
# fristbeginn = StringProperty(value)
self.root.fristbeginn = str(value)
Using KivyMD MDNavigationLayout, I'm trying to make a navigation drawer for an app! I did it that way, however my navigation drawer now moves across several screens! I only want it to appear on my HomeScreen, not my MenuScreen!
Thank you so much for what you've done.
KV Code:
MDScreen:
MDNavigationLayout:
ScreenManager:
HomeScreen:
id: home
MDBoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Navigation Drawer'
left_action_items: [['menu', lambda x: nav_drawer.set_state('toggle')]]
Widget:
MenuScreen:
id: menu
MDNavigationDrawer:
id: nav_drawer
<HomeScreen>:
name: 'home_screen'
MDLabel:
id: label
text: 'Home Screen'
halign: 'center'
MDRaisedButton:
text: 'Menu Screen'
pos_hint: {'center_x':0.5, 'center_y':0.4}
on_press: root.manager.current = 'menu_screen'
<MenuScreen>:
name: 'menu_screen'
MDLabel:
text: f'Menu Screen from Home Screen'
halign: 'center'
MDRaisedButton:
text: 'Home Screen'
pos_hint: {'center_x':0.5, 'center_y':0.4}
on_press: root.manager.current = 'home_screen'
HomeScreen:
MenuScreen:
The NavigationDrawer is a widget that is designed to work across many screens. It will show up across multiple screens. If we take a closer look at you.kv file we can figure out why. Notice how the MDNavigationLayout is above your Screenmanager. This means that all the Screens that come under your ScreenManager(A widget that basically manages your screen and allows you to switch between them easily) will be shown in the NavigationLayout.
There isn't really a way to exclude a Screen from showing the NavigationDrawer as the widget was designed to show itself across all screens that are under it
As can be seen here in the docs examples:
https://kivymd.readthedocs.io/en/0.104.1/components/navigation-drawer/[kivymd docs]1
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
KV = '''
<ContentNavigationDrawer>:
ScrollView:
MDList:
OneLineListItem:
text: "Screen 1"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 1"
OneLineListItem:
text: "Screen 2"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 2"
MDScreen:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "MDNavigationDrawer"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
MDNavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
MDScreen:
name: "scr 1"
MDLabel:
text: "Screen 1"
halign: "center"
MDScreen:
name: "scr 2"
MDLabel:
text: "Screen 2"
halign: "center"
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
'''
class ContentNavigationDrawer(MDBoxLayout):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
class TestNavigationDrawer(MDApp):
def build(self):
return Builder.load_string(KV)
TestNavigationDrawer().run()
https://kivymd.readthedocs.io/en/latest/components/navigationdrawer/#switching-screens-in-the-screenmanager-and-using-the-common-mdtoolbar
I M trying to add screen inside the screen manager but giving error of assertion when assigning navigation drawer in a screen manager.
This is the Error i am facing :
self._apply_rule(
File "/home/hp/.local/lib/python3.8/site-packages/kivy/lang/builder.py", line 559, in _apply_rule
assert(rule not in self.rulectx)
AssertionError
This is my Code:
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
screen_helper = """
ScreenManager:
MenuScreen:
ProfileScreen:
ContentNavigationDrawer:
<MenuScreen>:
name: 'menu'
MDRectangleFlatButton:
text: 'Profile'
pos_hint: {'center_x':0.5,'center_y':0.6}
on_press: root.manager.current = 'profile'
MDRectangleFlatButton:
text: 'Upload'
pos_hint: {'center_x':0.5,'center_y':0.5}
on_press: root.manager.current = 'upload'
<ProfileScreen>:
name: 'profile'
MDLabel:
text: 'Profile'
halign: 'center'
MDRectangleFlatButton:
text: 'Back'
pos_hint: {'center_x':0.5,'center_y':0.1}
on_press: root.manager.current = 'menu'
<ContentNavigationDrawer>:
name : 'upload'
ScrollView:
MDList:
OneLineListItem:
text: "Screen 1"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 1"
OneLineListItem:
text: "Screen 2"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 2"
Screen:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "MDNavigationDrawer"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
NavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
Screen:
name: "scr 1"
MDLabel:
text: "Screen 1"
halign: "center"
Screen:
name: "scr 2"
MDLabel:
text: "Screen 2"
halign: "center"
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
"""
class MenuScreen(Screen):
pass
class ProfileScreen(Screen):
pass
class ContentNavigationDrawer(Screen):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(ProfileScreen(name='profile'))
sm.add_widget(ContentNavigationDrawer(name='upload'))
class DemoApp(MDApp):
def build(self):
screen = Builder.load_string(screen_helper)
return screen
DemoApp().run()
I believe the problem is that your rule in screen_helper:
<ContentNavigationDrawer>:
includes:
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
That rule combination tells kivy that whenever it creates a ContentNavigationDrawer it should create another ContentNavigationDrawer as a child of the first. Then it would try to apply the original <ContentNavigationDrawer>: again, creating a third ContentNavigationDrawer, applying the rule again to create a fourth, and so on. This would create an infinite loop. Kivy uses the assertion to avoid such loops. So, you just cannot use a rule that would create such a loop.