Why KivyMD on_action_button is not working - python

Can anyone help me.When working with KivyMD in python syntax the on_action_button parameter of MDBottomAppBar(MDTopAppBar()) does not work.Can anyone guide me why does on_action_button: app.presser() is not working in kivymd
from kivymd.app import MDApp
from kivy.lang import Builder
class MyFirst_App(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "BlueGray"
return Builder.load_file("BottomBar.kv")
def presser(self):
print("hello")
MyFirst_App().run()
###############################KVFILE##########################################################
MDBoxLayout:
orientation: "vertical"
MDTopAppBar:
title: " Our Top Bar"
left_action_items: [["menu",lambda x: app.presser()]]
right_action_items: [["dots-vertical",lambda x: app.presser()]]
MDLabel:
id: my_label
text:"Some Stuff"
halign:"center"
MDBottomAppBar:
MDTopAppBar:
icon: "git"
#title: "Bottom Bar"
mode: "free-end"
#mode: "end"
#mode: "center"
#mode: "free-center"
on_action_button: app.presser()

You create the MDBottomAppBar icons the same way as the MDTopAppBar, just inside the MDBottomAppBar.
ie.
MDBottomAppBar:
MDTopAppBar:
left_action_items: [["account-circle",lambda x: app.presser()]]
right_action_items: [["account-child",lambda x: app.presser()],["account-child",lambda x: app.presser()]]

Related

How can I use one MDTopAppBar across multiple Screens in MDScreenManager?

I am developing an app in KivyMD for Python and I'm having trouble implementing a single MDTopAppBar for multiple screens.
Here's my current code:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.screenmanager import MDScreenManager
from kivymd.uix.screen import MDScreen
c = '''
<BuildApp>:
MDNavigationLayout:
MDScreenManager:
id: screener
FirstScreen:
SecondScreen:
MDNavigationDrawer:
id: nav_drawer
radius: (0, 16, 16, 0)
MDNavigationDrawerMenu:
MDNavigationDrawerItem:
icon: "android"
text: "Phone"
on_press: screener.current = "page2"
MDNavigationDrawerItem:
icon: "home"
text: "Home"
on_press: screener.current = "page1"
<FirstScreen>:
name: "page1"
MDBoxLayout:
orientation: 'vertical'
pos_hint: {"top": 1}
MDTopAppBar:
title: "Title"
elevation: 4
pos_hint: {"top": 1}
left_action_items: [["menu", lambda x: app.root.ids.nav_drawer.set_state("open")]]
MDFloatingActionButton:
icon: "home"
md_bg_color: app.theme_cls.primary_color
pos_hint: {"center_x":.5}
Widget:
<SecondScreen>:
name: "page2"
MDBoxLayout:
orientation: 'vertical'
pos_hint: {"top": 1}
MDTopAppBar:
title: "Title"
elevation: 4
pos_hint: {"top": 1}
left_action_items: [["menu", lambda x: app.root.ids.nav_drawer.set_state("open")]]
ScrollView:
MDList:
id: "stuffs"
OneLineListItem:
text: "Hi"
'''
class FirstScreen(MDScreen):
pass
class SecondScreen(MDScreen):
pass
sm= MDScreenManager()
sm.add_widget(FirstScreen(name="page1"))
class BuildApp(MDScreen):
pass
class DemoApp(MDApp):
def build(self):
global root_app
# self.theme_cls.theme_style = "Light"
self.theme_cls.primary_palette = "Yellow"
Builder.load_string(c)
root_app=BuildApp()
return root_app
DemoApp().run()
Since I can't accomplish the task, I manually coded a new MDTopAppBar for each MDScreen - It sucks, I know - but it's the only way I can implement my ideas given my limited knowledge of KivyMD. I hope you guys can help me. Thanks.

change state of action buttons on the toolbar in KivyMD

I'm trying to write an program for the phone in python using kivy md. The program dynamically adds modules to a page to be counted. I've already got that part sorted in simple kivy.
I'm now trying to replicate it in KivyMD because I can use a navigation drawer and it's screen manager. The program has 2 screens.
Is there way to change the state of the buttons in the action items according to the screen that is active?
So I'm trying to have 2 overlapped buttons on the right side of the toolbar and show button1 when screen 1 is active and hide button2 and vice-versa.
I used the example from KivyMD documentation on the NavDrawer with the Screen manager and built on that. The left action items is used for the navigation drawer and I am trying to add 2 more buttons on the right side an change their state according to the active screen.
I only managed to add one but I don't know how to add the second one and how to change their state.
Please see below the code I am using:
python file
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.app import MDApp
from kivymd.uix.scrollview import MDScrollView
class ContentNavigationDrawer(MDScrollView):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
class AbacApp(MDApp):
def build(self):
self.theme_cls.primary_palette = "Orange"
self.theme_cls.theme_style = "Dark"
return Builder.load_file('main.kv')
if __name__ == '__main__':
AbacApp().run()
kv file
<ContentNavigationDrawer>
MDBoxLayout:
orientation: "vertical"
MDAnchorLayout:
anchor_y: "top"
MDList:
TwoLineAvatarListItem:
text: "Abacu' lu' Lysu"
secondary_text: "Lisandru numara"
ImageLeftWidget:
source: "img.png"
MDList:
OneLineListItem:
text: "Module"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 1"
OneLineListItem:
text: "Printare"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 2"
MDScreen:
MDBottomAppBar:
MDTopAppBar:
pos_hint: {"bottom": 1}
elevation: 4
icon: "plus"
title: "Abacu' lu' Lisandru"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
on_action_button:
id: add_module
app.callback()
on_action_button:
id: print_modules
app.callback()
mode: "end"
MDNavigationLayout:
MDScreenManager:
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
radius: (0, 16, 16, 0)
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer

How do I switch screens with KivyMD toolbar

I made a very basic App, with KivyMD bottom App bar. I am having issues when I trying to use the toolbar icons to switch screen.
here's my main.py file (please bear with me, my code is a little clustered from me implementing some solutions I found, which didnt work)
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
Window.size = (300, 500)
class Screen1(Screen):
pass
class Screen2(Screen):
pass
class TwoScreenApp(MDApp):
def build(self):
self.theme_cls.primary_palette = 'Gray'
sm = ScreenManager()
sm.add_widget(Screen1(name='screen1'))
sm.add_widget(Screen2(name='screen2'))
return sm
def callback(self, screen):
self.current = screen
# root.manager.transition.direction = 'left'
# root.manager.current = 'screen2'
# link icon to screen2
TwoScreenApp().run()
here's my .kv file
ScreenManager:
Screen1:
Screen2:
<Screen1>
name: 'screen1'
MDBoxLayout:
md_bg_color: (255/255, 255/255, 255/255, 1)
orientation: 'vertical'
MDLabel:
halign: 'center'
text:
"""With the production of the Model T automobile,
Henry Ford had an unforeseen and tremendous
impact on American life. He became regarded
as an apt symbol of the transition from an
agricultural to an industrial America."""
MDBottomAppBar:
MDToolbar:
icon: "account-circle"
type: "bottom"
left_action_items: [["arrow-right", lambda x: root.manager.callback("screen1")]]
right_action_items: [["arrow-left", lambda x: x]]
elevation: 10
<Screen2>
name: 'screen2'
md_bg_color: (200/255, 200/255, 200/255, 1)
MDBoxLayout:
md_bg_color: (255/255, 255/255, 255/255, 1)
orientation: 'vertical'
MDLabel:
halign: 'center'
text:
"""The development of mass-production techniques, which
enabled the company eventually to turn out a Model T
every 24 seconds; the frequent reductions in the price
of the car made possible by economies of scale; and
the payment of a living wage that raised workers
above subsistence and made them potential customers
for, among other things, automobiles—these innovations
changed the very structure of society."""
MDBottomAppBar:
MDToolbar:
title: "Title"
icon: "account-circle"
type: "bottom"
left_action_items: [["menu", lambda x: x]]
I'll appreciate any help, thanks!
Your code:
left_action_items: [["arrow-right", lambda x: root.manager.callback("screen1")]]
is trying to call the callback() method of root.manager, which is the ScreenManager. But ScreenManager does not have a callback() method. I think you want to call the callback() method of your TwoScreenApp, which you would do like this:
left_action_items: [["arrow-right", lambda x: app.callback("screen2")]]
which uses the app keyword to reference the App instance.

How do I get KivyMD Navigation Drawer to call another app in a separate .py file?

I know how to write an app with kivy and I understand how to make a KivyMD app that has a navigation drawer. I can make the apps run individually but how do I combine the two?
I am new to coding and I am stuck here. Below are the codes for two mock-up apps for training purposes only. The first is a very simple app called "+5 Game" that allows the user to click a button to add 5 to the total which is then displayed in the GUI.
The second is a KivyMD app with a navigation drawer that contains two buttons. One to go to the home screen and one to go to the "+5 Game"
How do I link the button in the navigation draw to the +5 game?
And what do I do about the imports at the top of the file?
This is the code for the +5 Game:
from kivymd.app import MDApp
from kivymd.uix.screen import Screen
from kivymd.uix.label import MDLabel
from kivymd.uix.button import MDRectangleFlatButton
class ClickToAdd(MDApp):
def build(self):
self.screen = Screen()
self.num = 0
self.display_number = MDLabel(text="0", font_style="H1", halign="center",
pos_hint={'center_x': 0.5, 'center_y': 0.8})
self.add5_BTN = MDRectangleFlatButton(text="+5", pos_hint={'center_x': 0.5, 'center_y': 0.65},
on_release=self.add5_CMD)
self.screen.add_widget(self.display_number)
self.screen.add_widget(self.add5_BTN)
return self.screen
def add5_CMD(self, *args):
self.num = self.num + 5
self.display_number.text = str(self.num)
ClickToAdd().run()
This is the main GUI of the KivyMD app with a navigation drawer and a screen manager:
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
KV = '''
<ContentNavigationDrawer>:
ScrollView:
MDList:
OneLineListItem:
text: "Home"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "home"
OneLineListItem:
text: "Play +5 Game"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "plus5game"
Screen:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "Navigation Drawer Test"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
MDNavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
Screen:
name: "home"
MDLabel:
text: "Home Screen Stuff Goes Here"
halign: "center"
Screen:
name: "plus5game"
MDLabel:
text: "+5 Game Goes here"
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 cannot run one App inside another App, but you can use the guts of another App inside the first. In your case, you can redefine the the Plus5 App like this:
from kivymd.app import MDApp
from kivymd.uix.screen import Screen
from kivymd.uix.label import MDLabel
from kivymd.uix.button import MDRectangleFlatButton
class Plus5Screen(Screen):
def __init__(self, **kwargs):
super(Plus5Screen, self).__init__(**kwargs)
self.num = 0
self.display_number = MDLabel(text="0", font_style="H1", halign="center",
pos_hint={'center_x': 0.5, 'center_y': 0.8})
self.add5_BTN = MDRectangleFlatButton(text="+5", pos_hint={'center_x': 0.5, 'center_y': 0.65},
on_release=self.add5_CMD)
self.add_widget(self.display_number)
self.add_widget(self.add5_BTN)
def add5_CMD(self, *args):
self.num = self.num + 5
self.display_number.text = str(self.num)
class ClickToAdd(MDApp):
def build(self):
self.screen = Plus5Screen()
return self.screen
if __name__=='__main__':
ClickToAdd().run()
and save this is a file named plus5.py.
Then in you main App, you can just reference this in the 'kv':
KV = '''
#:import Plus5Screen plus5 # import the guts of the Plus5 game
<ContentNavigationDrawer>:
ScrollView:
MDList:
OneLineListItem:
text: "Home"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "home"
OneLineListItem:
text: "Play +5 Game"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "plus5game"
Screen:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "Navigation Drawer Test"
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
MDNavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
Screen:
name: "home"
MDLabel:
text: "Home Screen Stuff Goes Here"
halign: "center"
Plus5Screen: # this creates the guts of the Plu5 game
name: "plus5game"
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
'''

How to combine Navigation Drawer and multiple Screens in KivyMD (Python)?

I'm a coding beginner and I want to make a mobile app which contains a Toolbar with a Navigation Drawer and that one should bring the user to different screens in the app. I searched a lot around for a solution, but didn't really found one, because sometimes the whole code is in the .kv file, so it is hard to handle variables and print them for example such as in this code:
How to switch between screens within the NavigationDrawer using KivyMD
I tried to combine it with this code which uses only Kivy instead of KivyMD but I failed bacause it isn't really for mobile Apps:
https://www.techwithtim.net/tutorials/kivy-tutorial/multiple-screens/
I hope someone can help me.
Thx!
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
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"
Screen:
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
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()
https://kivymd.readthedocs.io/en/latest/components/navigation-drawer/#switching-screens-in-the-screenmanager-and-using-the-common-mdtoolbar

Categories