''' Suite of Application Builders ============================= This explores different methods of starting an application. If you run this without a command line parameter, you should see a menu in your terminal. You can also run this with a 'r' parameter to pick a random method. There are lots of logging options to make this easier to debug: the execution order may not be obvious. Each time you run the command, only one kivy application is created. This uses the file testkvfile.kv and the file app_suite_data/testkvdir.kv. ''' from __future__ import print_function import sys import re from random import choice import kivy kivy.require('1.8.0') # 1.8 is when kv_directory became part of app. from kivy.app import App from kivy.uix.button import Button from kivy.lang import Builder from kivy.uix.floatlayout import FloatLayout # Note that importing FloatLayout causes Kivy to execute, including # starting up the Logger and some other messages. print("** In main program, done with imports") class TestBuildApp(App): """ Use build() function to return a widget. """ def build(self): """ Build called by kivy when an App is started. Called after trying to load a .kv file. Returns a new Button as a root widget. """ print("** inside build()") return Button(text='hello from TestBuildApp') class TestKVFileApp(App): """ Empty class, but name used to find .kv file. The filename is the lowercase version of the class, i.e. 'testkvfileapp.kv'. If not found, it strips off the final 'app', i.e. 'testkvfile.kv'. If not file is found, and no other method sets the self.root, the program will run with an empty screen. """ pass class TestKVDirApp(App): """ Empty class except for setting class variable kv_directory. This directory sets the directory in which to search for the .kv file. The name of the kv file is still governed by the class name and the .kv file should still have one root widget. """ kv_directory = 'app_suite_data' class TestKVStringApp(App): """ Use a build() function and use the kivy.lang.Builder function to parse up a Kivy language string. """ def build(self): """ Called by kivy run(). """ print("** inside build()") widget = Builder.load_string( "Button:\n text: 'hello from TestKVStringApp'") print("** widget built") return widget class TestPrebuiltApp(App): """ Use the Builder to create a top level widget at the beginning of the Python program, then use a dummy class for that widget. This costs a bit more in start-up time. """ kv = "\n Button:\n text:'hello from TestPrebuiltApp'" Builder.load_string(kv) print("** in TestPrebuiltApp, class initialization built ") class Prebuilt(FloatLayout): """ Empty class to cause setting root to tag and set inheritance """ pass def build(self): """ called, returns instance matching tag . """ return self.Prebuilt() def print_class(class_name): """ Read this file and print the section with the class name specified.)""" filename = sys.argv[0] with open(filename) as f: data = f.read() regex = "^(class " + class_name + "\\b.*?)^\\S" match = re.search(regex, data, flags=re.MULTILINE | re.DOTALL) if match: print(match.group(1)) # the __name__ idiom executes when run from command line but not from import. if __name__ == '__main__': dash = "-" * 40 arg = sys.argv[1][0].lower() if len(sys.argv) > 1 else "h" print(dash) if arg == 'r': arg = choice('bfds') if arg == 'b': print_class("TestBuildApp") TestBuildApp().run() elif arg == 'f': print_class("TestKVFileApp") TestKVFileApp().run() elif arg == 'd': print_class("TestKVDirApp") TestKVDirApp().run() elif arg == 's': print_class("TestKVStringApp") TestKVStringApp().run() elif arg == 'p': print_class("TestPrebuiltApp") TestPrebuiltApp().run() else: # help print(""" This demo runs different application windows based on a command line argument. Try using one of these: b - Use build() method to return a widget d - Use a kv file from a different directory f - Use a kv file with the widget object p - Use prebuilt widget inside a layout s - Use a kivy language string to create the widget r - pick one of the options at random. h - show this help message. After closing the application window, this program will exit. While the run() method does return, kivy cannot run another application window after one has been closed. """) print(dash) print("This program is gratified to be of use.")