I am trying to switch screens in kivy and I have been stuck on this for a while so I don't know what is going on. The text is being printed but the screen is still not changing. Here is the python code if anyone can help me out:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
from kivymd.uix.button import MDFloatingBottomButton
Window.size = (300, 500)
class MainScreen(Screen):
def switch_button(self):
print("switching")
ScreenManager.current = "FileScreen"
class FileScreen(Screen):
pass
class app(MDApp):
data = {
'Create': 'file-document',
'Open': 'folder-open'
}
def btn(self, instance):
print('callback')
icon = instance.icon
# if you want check button, use
if isinstance(instance, MDFloatingBottomButton):
if icon == 'file-document':
print('Create')
MainScreen.switch_button(self)
elif icon == 'folder-open':
print('Open')
class ContentNavigationDrawer(BoxLayout):
pass
class DrawerList(ThemableBehavior, MDList):
pass
sm = ScreenManager()
sm.add_widget(MainScreen(name='MainScreen'))
sm.add_widget(FileScreen(name='FileScreen'))
def build(self):
self.theme_cls.primary_palette = "Red"
#self.theme_cls.accent_palette = "Teal"
screen = Builder.load_file("main.kv")
return screen
app().run()
Here is the .KV
code:
ScreenManager:
MainScreen:
FileScreen:
<MainScreen>:
name: "MainScreen"
MDFloatingActionButtonSpeedDial:
bg_hint_color: app.theme_cls.primary_light
data: app.data
root_button_anim: True
callback: app.btn
<FileScreen>:
name: "FileScreen"
MDBoxLayout:
MDLabel:
text: "test"
I hope the community can help me as soon as they can because if have been stuck on this for a while.
It appears that you are confusing classes and instances. In your switch_button()
method your code:
ScreenManager.current = "FileScreen"
is setting the current
attribute of the ScreenManager
class, but the current
property is an instance property and must be set on an instance of ScreenManager
. And it must be the instance that is managing the FileScreen
Screen
.
A better coding of the switch_button()
method:
class MainScreen(Screen):
def switch_button(self):
print("switching")
self.manager.current = "FileScreen"
The self.manager
is a reference to the ScreenManager
that is managing the MainScreen
, which is also managing the FileScreen
.
Elsewhere, you are making a similar confusion between class and instance:
MainScreen.switch_button(self)
Again, you need the instance of MainScreen
, not the MainScreen
class. This line can be replaced by:
self.root.get_screen('MainScreen').switch_button()
This code uses the get_screen()
method of ScreenManager
to access the instance of MainScreen
, then calls the instance method switch_button()
.
A more direct approach would be to replace that line with:
self.root.current = 'FileScreen'