My kivy app has nearly 100 screens. I am using ScreenManager to load the screens on startup (code below), but this is causing the app to take 30 seconds to load. Is there a more efficient way to handle screens in kivy, so screens only load when they are needed instead of loading all screens at app launch? I've seen kivy's switch_to(), but I'm unsure of how to use this instead of the on_press: root.manager.current = 'login' in a Button widget, for instance, or if switch_to() is even appropriate for this use case. What is the best practice for efficiently loading and switching between screens in a kivy app that has many screens?
class LoginScreen(Screen):
...
class GameApp(App):
sm = ScreenManager()
def build(self):
self.sm.add_widget(LoginScreen(name='login'))
self.sm.add_widget(SignUpScreen(name='signup'))
...
My kivy app has nearly 100 screens. I am using ScreenManager to load the screens on startup (code below), but this is causing the app to take 30 seconds to load. Is there a more efficient way to handle screens in kivy, so screens only load when they are needed instead of loading all screens at app launch?
Yes, code the screen caching yourself, e.g. with your own method that does whatever you want (e.g. unloading screens if too many are present, creating the new screen if it doesn't exist yet, showing the new screen by setting .current etc.)
I've seen kivy's switch_to()
switch_to() just takes a new screen, removes the old one entirely, and shows the new one (unlike just setting .current, which doesn't remove the old one entirely). You might find it convenient, but it doesn't directly solve your problem.
Related
To me both ScreenManager and Tabs seem like they do the same thing, what advantages/disadvantages of using one over the other?
The main difference is that both are used for managing multiple screens in the kivy application.
1. ScreenManager
clear and simple
easy navigation and dynamic
require more coding and setup
difficult to manage
1. Tabs
Tabs provide an intuitive and familiar interface for users
easy to set up
difficult to navigate
when you have more screens it becomes cluttered
Well hi, just signed up for this question.
Ive started working with Kivy this week, so far so good, I guess. Im making some sort of POS software, so far I've done things separately, a folder for each module, dashboard(this one module has other modules, sales, providers, products, clients, reports, etc.), operator, and login. I have a main.py and main.kv on root folder, in main.kv I have a ScreenManager that opens the login form on start and then takes me to either operator or dashboard depending the user. Thing is dashboard has another ScreenManager, so i can switch between the other modules that it has in it, it works on standalone but when i call it on main.py withing main.kv it crashes, it doesn't seem to accept two ScreenManager widgets.
My goal is to:
Apparently i cant post GIF yet.
The dashboard works like the gif when I run the dashboard.py file alone but when invoked in main.py it crashes, to be able to run I've to remove the ScreenManager widget class from dashboard.kv and ofc the container that holds the screen widgets crashes it displays all the other modules at once.
I thought about using the add_widget method and threat the screen widgets like a regular box widget but figured that it would just spam the widget on every click like one on top of the other and i think using the clear_widget to remove the previous widget would be just too hard coded, plus I would loose the transition animation
Question is, how can i achieve mentioned goal?
sorry about the gif, it was a 5 mins blender thing.
also English, not main. :s
I am developing a GUI with Python/ Kivy, which consists out of several Screens that contain a variety of Kivy widgets (TextInput, Spinner, DropDown, CheckBox, Label,...). I am using Buttons and the ScreenManager to switch between different screens. The problem I am facing is that after switching screens, the input data is still saved in the widgets. My aim is that after the data has been entered and submitted to a database, the input will then be deleted from the kivy widgets.
What options does kivy offer, to reset the input data for an entire screen after a specific event (Button, ScreenChange, etc.)? The only thing I came up with, was defining a function reset_screen for every single screen, which will delete the entire input data of a screen. Is it possible to somehow save the default status of a screen and then call it again after an event?
Thanks!
I am trying to open one GUI from a completely different GUI. I am developing on a desktop and the windows have different sizes from each other. I looked at screen manager but I feel as if there is an easier way to do this.
Thanks in advance!
It's possible, but kinda inconvenient. The issue is that kivy supports only one window per app, so you need to work around it somehow. I personally just use multiple *Layouts (which are different GUIs with different functions) in a single window, showing and hiding them as necessary. Obviously this approach has its restrictions, eg it doesn't support multiple monitors, but it's as simple as it gets.
Then there is a question here on SO where people spawn separate kivy apps for every window, thus getting windows that can be dragged and resized relatively. It requires some fiddling with subprocesses and communicating between apps, but this method is more powerful.
ScreenManager, as I understand, doesn't help you: it allows just to define multiple widget trees for the same window and switch between them on the fly. It's a normal use case on touchscreens, but makes pretty little sense on desktop. Which is true for quite a few things in kivy, to be honest. If you don't plan to move to mobiles later, Tkinter or PyQT may be a better choice than kivy.
You can use PageLayout or ScreenManager. They can create multiple screen (NOT WINDOWS) at a time. They can be really helpful! Because kivy doesn't support multiple windows, you can use those.
from kivy.uix.pagelayout import PageLayout
from kivy.uix.screenmanager import Screen, ScreenManager. FadeTransition
At the moment I have one Floatlayout in SHeditorMain, Inside the class SHeditormain i've declared a bunch of widgets (buttons, popups, labels, etc..) and used self.add_widget to add them.
Now i want to create a new window that opens up inside/over the FloatLayout and i can't seem to get it to works. All the examples i've seen so far regarding multiple windows is either using App as main class for the creation of widgets inside the layouts. Any suggestions or do i have to restructure the code?
class SHeditorMain(FloatLayout):
def __init__(self, **kwargs):
super(SHeditorMain, self).__init__(**kwargs)as
self.add_widget(blabla)
self.add_widget(blabla)
self.add_widget(blabla)
self.add_widget(blabla)
self.dbconnection = DBconnection()
#declare popups etc
def functionEvents(self, instance):
yaddayadda
def functionEvents(self, instance):
yaddayadda
def functionEvents(self, instance):
yaddayadda
class SHeditor(App):
def build(self):
self.root = SHeditorMain()
return self.root
Please read this answer about multiple "windows" and why it may not be desired. I can recommend you to have kivy window maximized and using ModalView as a pseudo-form that can be dragged and has some button that would close it. More control over everything, cleaner code, beginner friendly. Create a custom widget that inherits from ModalView and what it does is up to you.
You can place modals wherever you want them to be - look into popup source code in repo how the positions are set. You'll basically end up with a custom Popup that you can control without crippling the original widget.
Another way may be to use ScreenManager(or PageLayout, Carousel, xyz other widgets) which provide mobile-/presentation-like view. The sooner you get to kv language, the sooner you'll have less troubles to imagine that stuff out of pocket e.g. you see a fancy app, you can open kivy-designer or for more control/less fancy go for KivyCatalog and just type what you see that's how straightforward the kvlang is.
Example with Modals:(old attempt to create windows-like... something via Kivy = FloatLayout with Scatter(only drag enabled) as "windows")
Which leads me to the conclusion that if you think you need multiple windows or another window would be nice for whatever reason but you are not sure if it'd work or something - you actually don't and you are overcomplicating things, which steal your attention from the important parts of your code to UI.
(PS, I'd edit the answer mentioned at the top, but in that question user has a little bit more complicated problem)