-
Notifications
You must be signed in to change notification settings - Fork 55
Home
- Our First Dev Sprint meant to get people familiarized with kivy.
After this first Devspring it was decided that we would start working on the app from scratch.
For this purpose the master
branch was emptied and we have started with blank dir.
Step 1: We setup a basic structure for the app
PyCon-Mobile-App
|
|___ LICENSE
|___ Makefile
|___ README.md
|___ eventsapp
|___ main.py: "This is the main entry point of our application"
|___ uix: "This is where our user interface elements go."
|___ screens: "This is where all our UI screens of the app go."
|
|___ tools: "This is where all our tools including assets etc go."
|___ images: "This is where all our image assets go."
|___ raw_assets: "This is where our raw assets from the design team exist."
|___ tests: "All our tests go here"
This is the current app structure, Currently the main.py just has the following data.
from kivy.app import App
class EventsApp(App):
'''This is our entry point for the application
'''
def on_pause(self):
# allow the app to pause on android and ios
# set this to False if you do not want that.
return True
def on_resume(self):
pass
# is our app running as main or is it being imported as a module?
if __name__ == '__main__':
# our app is running as main
# let us instantiate the app and run it.
EventsApp().run()
Now run this APP.
python main.py
So this gives you just one simple blank window with nothing in there.
Keeping in mind the following items::
We will be sending out a mail to each volunteer group asking for their input on how they want to use the app. This should help us get a better idea of how to have the app designed.
Till that we will be starting with a basic app loads basic screens
Starting from the blank screen in step one,
The first thing that happens in our app should be the display of logo on splash screen.
Now what is a ScreenManager
?
[ ] Your physical screen
[ ] Screen Manager
[1] [2] [3] Screens 1, 2 & 3
At any given point a screen manager would show you a one of the screens 1, 2 or 3.
This allows you to have many screens designed and available ready to be brought inside
the physical screen for display based on any event.
A ScreenManager
is a Widget
that houses multiple screens
that can be loaded in it
using different types of transitions, for more info in the subjects please look at
https://kivy.org/docs/api-kivy.uix.screenmanager.html
What is a splash screen
?
(Wiki) https://en.wikipedia.org/wiki/Splash_screen has a good explanation. Basically it is a Image + Logo, anything that gives the user a idea of what the product does. Some splash screens include versions some do not, look at the wiki for more details.
Now that every one knows what's a splash screen and a ScreenManager
, let's make sure that
the root
Widget of our app is a screen Manager.
https://github.com/pythonindia/PyCon-Mobile-App/blob/master/eventsapp/main.py#L38
The way we do this is to return ScreenManager
widget's instance in the build
method of the app
class.
class EventsApp(App):
'''This is our entry point for the application
'''
def build(self):
from kivy.uix.screenmanager import ScreenManager
root = ScreenManager()
#return the root widget here
return root
Now What is a root widget?
Consider a Tree
0 This is our root
/ \
0 0
/ \ / \
0 0 0 0
A root widget in terms of the UI tree is the widget that sits at top of everything under it and has no other widget on top of it.
At any given time app.root points to one root widget by default this is the one returned by the build method.
Now that we understand what is a root widget, and that we
have ScreenManager
as our current root of the app, we can
move forward to creating screens for this manager.
Let's first add a load_screen
method in our main.py.
This method could be used/called by any place in our app
to load a screen in any given ScreenManager
.
This method is supposed to be used like this::
app_instance.load_screen('ScreenName')
As a example look at this line
What does this function do?(Only for advanced users, most people do not need to know how and why this works).
A module_path has been setup before hand to be used by, load_screen('ScreenName')
for loading the screens, in our case this is uix/screens
.
So this method, load_screen
looks for a module screenname.py
in directory uix/screens/
, under the directory where main.py resides and imports it.
Then this imports the class ScreenName
from that file and instantiates it. Then this adds it to the screen manager instance.
ok, now that we have a method to load a screen in the ScreenManager, we need to create and load our LogoScreen
or splash screen
.
Let's create a new dir, uix
under the eventsapp
folder, add a blank __init__.py
in it, so this folder can be imported as a module, then do the same for uix/screens
folder adding a __init__.py under it.
.
cd PyCon-Mobile-App/eventsapp
mkdir uix
touch uix/__init__.py
mkdir uix/screens
touch uix/screens/__init__.py
Next let's create our splash screen
.
touch uix/screens/logoscreen.py
Open this file in a editor of your choice.
'''
logo_screen:
=============
Display the logo
'''
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
class LogoScreen(Screen):
''' The screen responsible for displaying a Logo, Splash.
'''
Builder.load_string('''
<LogoScreen>
name: 'LogoScreen'
''')
Important thing to note here. In order to define the UI of any widget,
you have to write a rule in KV language denoted by <NameOfWidget>
.
Let's just keep this blank for now, and just setup the name of the screen.
Note:: name: 'LogoScreen'
, part is important and should be the same
as the name of the class itself.
If we save and run this file, we will see nothing happen, why?
Cause there is nothing inside this screen. Let's add the Splash Image.
First let's take the splash screen from the raw_assets folder, add it to our data/images folder.
Next let us design the UI for this screen.
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
class LogoScreen(Screen):
Builder.load_string('''
<LogoScreen>
name: 'LogoScreen'
Image
source: 'data/images/background.png'
allow_stretch: True
''')
Let's save this file and run the app.
python main.py
What do you see?
You see a image on the screen but it is not taking up the entire screen.
Furthermore why is this showing us a square window when we should be designing the app for a mobile?
Let's try and emulate a mobile screen.
python main.py -m screen:droid2,portrait
That's a bit better? Screen should now emulate the appearance of a Droid2 mobile in portrait mode.
Next let us add the PyCon India logo
'''
logo_screen:
=============
Display the logo
'''
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
class LogoScreen(Screen):
Builder.load_string('''
<LogoScreen>
name: 'LogoScreen'
Image
source: 'data/images/background.png'
allow_stretch: True
Image
id: logo_img
source: 'data/images/logo.png'
allow_stretch: True
pos_hint: {'center_x': .5, 'center_y': .5}
''')
So, we just add a simple Image on top of the earlier Image, and make sure it is centered using pos_hint
,
pos_hint: {'center_x': .5, 'center_y': .5}
signifies we want the widget to be centered in it's parent.
Let's animate the logo.
'''
logo_screen:
=============
Display the logo
'''
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
class LogoScreen(Screen):
Builder.load_string('''
<LogoScreen>
name: 'LogoScreen'
on_enter:
from kivy.animation import Animation
Animation(opacity=1, size=(root.width - dp(90), root.height), d=.5).start(logo_img)
Image
source: 'data/images/background.png'
allow_stretch: True
Image
id: logo_img
opacity: 0
source: 'data/images/logo.png'
allow_stretch: True
size_hint: None, None
size: 0, 0
pos_hint: {'center_x': .5, 'center_y': .5}
'''
The part that animates
the widget is this::
...
on_enter:
from kivy.animation import Animation
Animation(opacity=1, size=(root.width - dp(90), root.height), d=.5).start(logo_img)
So when this screen enters the visible space, a on_enter
event is called, where we 1) import Animation, 2) set Animation to happen on opacity and size of the widget. We also make sure to set the opacity and size of the widget to 0 & (0, 0) respectively.
If we follow the wireframe the next logical step is to design a NavigationDrawer.
For this we create a new file named NavigationScreen in the uix/screens
folder, make sure to load it by default when the app starts.
We do this on the LogoScreen once we are done animating the logo.
To the Navigation Drawer
Now all we need to do is create a simple screen like we did before. This is a simple About Screen with a Button
.
We load this screen inside the ScreenManager
inside the NavigationDrawer
Button
text: 'About'
on_release:
app.navigation_screen.ids.drawer.toggle_state()
app.load_screen('AboutScreen', manager=app.navigation_screen.ids.nav_manager)
Here first, when the About Button, is released, on_release
we first access the navigation_screen using the app.navigation_screen
attribute. However where did we set this?
Look at line No. 99
Here we set the attribute app.navigation_screen
when the Screen is first loaded into it's manager.
Ok, now that we have access to the screen, we can access all the id
under it like so.
so, here we toggle the drawer and load the screen named AboutScreen
.
That's it, this is how you create and add a new screen.
Next steps TODO: Feel free to take up tasks from below
- Adding a Navigation Drawer. [Quanon: Complete][ToDo: Documentation]
- Adding a Buttons to Navigation Drawer [Quanon: ToDo]
- Setting ScreensManager inside NavigationDrawer[Quanon: Copmlete ToDo: Documnetation]
- Getting and sending data as Push Notification(Serverside + Firebase integration)
- Adding & loading screens to this ScreenManager inside Navigation drawer based on which button was selected.See example above.
Screens for
- Welcome Screen
- Schedule
- Speaker Page
- Venue
- About(10% done)
- Community
- Tickets
- Open Spaces
- Sponsors