ae.gui_app

base class for python applications with a graphical user interface

the abstract base class MainAppBase provided by this ae namespace portion allows the integration of any Python GUI framework into the ae namespace.

on overview about the available GUI-framework-specific ae namespace portion implementations can be found in the documentation of the ae namespace portion ae.lisz_app_data.

extended console application environment

the abstract base class MainAppBase inherits directly from the ae namespace class ae console application environment class. the so inherited helper methods are useful to log, configure and control the run-time of your GUI app via command line arguments.

Hint

please see the documentation of config options and config files in the ae.console namespace portion/module for more detailed information.

MainAppBase adds on top of the ConsoleApp the concepts of application events, application status and application flow, explained further down.

application events

the events described in this section are fired on application startup and shutdown. additional events get fired e.g. in relation to the app states (documented further down in the section app state events) or on start or stop of an app tour.

the following application events are fired exactly one time at startup in the following order:

  • on_app_init: fired after ConsoleApp app instance got initialized (detected config files) and before the image and sound resources and app states get loaded and the GUI framework app class instance gets initialized.

  • on_app_run: fired from within the method run_app(), after the parsing of the command line arguments and options, and before all portion resources got imported.

  • on_app_build: fired after all portion resources got loaded/imported, and before the framework event loop of the used GUI framework gets started.

  • on_app_started: fired after all app initializations, and the start of and the initial processing of the framework event loop.

Note

the application events on_app_build and on_app_started have to be fired by the used GUI framework.

Hint

depending on the used gui framework there can be more app start events. e.g. the ae.kivy.apps module fires the events on_app_built() and on_app_start() (all of them fired after on_app_run() and on_app_build()). see also kivy application events.

when an application gets stopped then the following events get fired in the following order:

  • on_app_exit: fired after* framework win got closed and just **before the event loop of the GUI framework will be stopped and the app shutdown.

  • on_app_quit: fired after the event loop of the GUI framework got stopped and before the AppBase.shutdown() method will be called.

Note

the on_app_exit events will only be fired if the app is explicitly calling the stop_app() method.

Hint

depending on the used gui framework there can be more events. e.g. the apps module fires the events on_app_stop() and clock tick later on_app_stopped() (both of them before on_app_quit() get fired). see also kivy application events.

application status

any application- and user-specific configurations like e.g. the last window position/size, the app theme/font/language or the last selected flow within your app, could be included in the application status.

this namespace portion introduces the section aeAppState in the app config files, where any status values can be stored persistently to be recovered on the next startup of your application.

Hint

the section name aeAppState is declared by the APP_STATE_SECTION_NAME constant. if you need to access this config section directly then please use this constant instead of the hardcoded section name.

app state variables

this module is providing/pre-defining the following application state variables:

which app state variables are finally used by your app project is (fully data-driven) depending on the app state config variables detected in all the config files that are found/available at run-time of your app. the names of all the available application state variables can be determined with the main app helper method app_state_keys().

if no config-file is provided then this package ensures at least the proper initialization of the following app state variables:

if your application is e.g. supporting a user-defined font size, using the provided/pre-defined app state variable font_size, then it has to call the method change_app_state() with the argument of app_state_name set to font_size every time when the user has changed the font size of your app.

Hint

the two built-in app state variables are flow_id and flow_path will be explained detailed in the next section.

the load_app_states() method is called on instantiation from the implemented main app class to load the values of all app state variables from the config files, and is then calling :meth:~MainAppBase.setup_app_states` for pass them into their corresponding instance attributes.

use the main app instance attribute to read/get the actual value of a single app state variable. the actual values of all app state variables as a dict is determining the method retrieve_app_states(), and can be saved into the config files for the next app run via the method save_app_states() - this could be done e.g. after the app state has changed or at least on quiting the application.

always call the method change_app_state() to change an app state value to ensure:

  1. the propagation to any duplicated (observable/bound) framework property and

  2. the event notification of the related (optionally declared) main app instance method.

app state constants

this module is also providing some pre-defined constants that can be optionally used in your application in relation to the app states data store and for the app state config variables app_state_version, font_size and light_theme:

app state events

there are three types of notification events get fired in relation to the app state variables, using the method names:

  • on_<app_state_name>: fired if the user of the app is changing the value of an app state variable.

  • on_<app_state_name>_save: fired if an app state gets saved to the config file.

  • on_app_state_version_upgrade: fired if the user upgrades a previously installed app to a higher version.

the method name of the app state change notification event consists of the prefix on_ followed by the variable name of the app state. so e.g. on a change of the font_size app state the notification event on_font_size will be fired/called (if exists as a method of the main app instance). these events don’t provide any event arguments.

the second event gets fired for each app state value just after the app states getting retrieved from the app class instance, and before they get stored into the main config file. the method name of this event includes also the name of the app state with the suffix _save, so e.g. for the app state flow_id the event method name will result in on_app_state_flow_id_save(). this event is providing one event argument with the value of the app state. if the event method returns a value that is not None then this value will be stored/saved.

the third event gets fired on app startup when the app got upgraded to a higher version of the app state variable APP_STATE_VERSION_VAR_NAME (app_state_version). it will be called providing the version number for each version to upgrade, starting with the version of the previously installed main config file, until the upgrade version of the main config file get reached. so if e.g. the previously installed app state version was 3 and the new version number is 6 then this event will be fired 3 times with the argument 3, 4 and 5. it can be used e.g. to change or add app state variables or to adapt the app environment.

application flow

to control the current state and UX flow (or context) of your application, and to persist it until the next app start, MainBaseApp provides two app state variables: flow_id to store the currently working flow and flow_path to store the history of nested flows.

an application flow is represented by an id string that defines three things: (1) the action to enter into the flow, (2) the data or object that gets currently worked on and (3) an optional key string that is identifying/indexing a widget or data item of your application context/flow.

Note

never concatenate a flow id string manually, use the id_of_flow() function instead.

the flow id is initially an empty string. as soon as the user is starting a new work flow or the current selection your application should call the method change_flow() passing the flow id string into the new_flow_id argument to change the app flow.

for more complex applications you can specify a path of nested flows. this flow path gets represented by the app state variable flow_path, which is a list of flow id strings.

to enter into a deeper/nested flow you simply call change_flow() with one of the actions defined in ACTIONS_EXTENDING_FLOW_PATH.

to go back to a previous flow in the flow path call change_flow() passing one of the actions defined in ACTIONS_REDUCING_FLOW_PATH.

application flow change events

the flow actions specified by ACTIONS_CHANGING_FLOW_WITHOUT_CONFIRMATION don’t need a flow change confirmation event handler:

  • ‘enter’ or ‘leave’ extend/reduce the flow path.

  • ‘focus’ pass/change the input focus.

  • ‘suggest’ for autocompletion or other suggestions.

all other flow actions need to confirmed to be changed by change_flow(), either by a custom flow change confirmation method/event-handler or by declaring a popup class. the name of the event handler and of the popup class gets determined from the flow id.

Hint

the name of the flow change confirmation method that gets fired when the app want to change the flow (via the method change_flow()) gets determined by the function flow_change_confirmation_event_name(), whereas the name of the popup class get determined by the function flow_popup_class_name().

if the flow-specific change confirmation event handler does not exist or returns in a boolean False or None then on_flow_change() will be called. if this call also returns False then the action of the new flow id will be searched within ACTIONS_CHANGING_FLOW_WITHOUT_CONFIRMATION and if not found then the flow change will be rejected and change_flow() returns False.

if in contrary either the flow change confirmation event handler exists and does return True or on_flow_change() returns True or the flow action of the new flow id is in ACTIONS_CHANGING_FLOW_WITHOUT_CONFIRMATION then the flow id and path will be changed accordingly.

after the flow id/path change confirmation the method change_flow() checks if the optional event_kwargs key changed_event_name got specified and if yes then it calls this method.

finally, if a confirmed flow change results in a ‘focus’ flow action then the event on_flow_widget_focused will be fired. this event can be used by the GUI framework to set the focus to the widget associated with the new focus flow id.

flow actions ‘open’ and ‘close’

to display an instance of a properly named popup class, simply initiate the change the app flow to an appropriate flow id (with an ‘open’ flow action). in this case no change confirmation event handler is needed, because on_flow_change() is then automatically opening the popup.

when the popup is visible the flow path will be extended with the respective flow id.

calling the close method of the popup will hide it. on closing the popup the flow id will be reset and the opening flow id will be removed from the flow path.

all popup classes are providing the events on_pre_open, on_open, on_pre_dismiss and on_dismiss. the on_dismiss event handler can be used for data validation: returning a non-False value from it will cancel the close.

Hint

see the documentation of each popup class for more details on the features of popup classes (for Kivy apps e.g. FlowDropDown, FlowPopup or FlowSelector).

key press events

to provide key press events to the applications that will use the new GUI framework you have to catch the key press events of the framework, convert/normalize them and then call the key_press_from_framework() with the normalized modifiers and key args.

the modifiers arg is a string that can contain several of the following sub-strings, always in the alphabetic order (like listed below):

  • Alt

  • Ctrl

  • Meta

  • Shift

the key arg is a string that is specifying the last pressed key. if the key is not representing a single character but a command key, then key will be one of the following strings:

  • escape

  • tab

  • backspace

  • enter

  • del

  • enter

  • up

  • down

  • right

  • left

  • home

  • end

  • pgup

  • pgdown

on call of key_press_from_framework() this method will try to dispatch the key press event to your application. first it will check the app instance if it has declared a method with the name on_key_press_of_<modifiers>_<key> and if so it will call this method.

if this method does return False (or any other value resulting in False) then method key_press_from_framework() will check for a method with the same name in lower-case and if exits it will call this method.

if also the second method does return False, then it will try to call the event method on_key_press of the app instance (if exists) with the modifiers and the key as arguments.

if the on_key_press method does also return False then key_press_from_framework() will finally pass the key press event to the original key press handler of the GUI framework for further processing.

integrate new gui framework

to integrate a new Python GUI framework you have to declare a new class that inherits from MainAppBase and implements at least the abstract method init_app().

additionally and to load the resources of the app (after the portions resources got loaded) the event on_app_build has to be fired, executing the MainAppBase.on_app_build() method. this could be done directly from within init_app() or by redirecting one of the events of the app instance of the GUI framework.

a minimal implementation of the init_app() method would look like the following:

def init_app(self):
    self.call_method('on_app_build')
    return None, None

most GUI frameworks are providing classes that need to be instantiated on application startup, like e.g. the instance of the GUI framework app class, the root widget or layout of the main GUI framework window(s). to keep a reference to these instances within your main app class you can use the attributes framework_app, framework_root and framework_win of the class MainAppBase.

the initialization of the attributes framework_app, framework_root and framework_win is optional and can be done e.g. within init_app() or in the on_app_build application event fired later by the framework app instance.

Note

if framework_win is set to a window instance, then the window instance has to provide a close method, which will be called automatically by the stop_app().

a typical implementation of a framework-specific main app class looks like:

from new_gui_framework import NewFrameworkApp, MainWindowClassOfNewFramework

class NewFrameworkMainApp(MainAppBase):
    def init_app(self):
        self.framework_app = NewFrameworkAppClass()
        self.framework_win = MainWindowClassOfNewFramework()

        # return callables to start/stop the event loop of the GUI framework
        return self.framework_app.start, self.framework_app.stop

in this example the on_app_build application event gets fired either from within the start method of the framework app instance or by an event provided by the GUI framework.

init_app() will be executed only once at the main app class instantiation. only the main app instance has to initialize the GUI framework to prepare the app startup and has to return at least a callable to start the event loop of the GUI framework.

Hint

although not recommended because of possible namespace conflicts, one could e.g. alternatively integrate the framework application class as a mixin to the main app class.

to initiate the app startup the run_app() method has to be called from the main module of your app project. run_app() will then start the GUI event loop by calling the first method that got returned by init_app().

optional configuration and extension

most of the base implementation helper methods can be overwritten by either the inheriting framework portion or directly by user main app class.

base resources for your gui app

this portion is also providing base resources for commonly used images and sounds.

the image file resources provided by this portion are taken from:

the sound files provides by this portion are taken from:

Hint

the i18n translation texts of this module are provided by the ae namespace portion ae.gui_help.

TODO: implement OS-independent detection of dark/light screen mode and automatic notification on day/night mode switch. - see https://github.com/albertosottile/darkdetect for MacOS, MSWindows and Ubuntu - see https://github.com/kvdroid/Kvdroid/blob/master/kvdroid/tools/darkmode.py for Android

Module Attributes

APP_STATE_SECTION_NAME

config section name to store app state

APP_STATE_VERSION_VAR_NAME

config variable name to store the current application state version

COLOR_BLACK

!= 0/1 to differentiate from framework pure black/white colors

THEME_DARK_BACKGROUND_COLOR

dark theme background color in rgba(0.0 .

THEME_DARK_FONT_COLOR

dark theme font color in rgba(0.0 .

THEME_LIGHT_BACKGROUND_COLOR

light theme background color in rgba(0.0 .

THEME_LIGHT_FONT_COLOR

light theme font color in rgba(0.0 .

MIN_FONT_SIZE

minimum (s.a.

MAX_FONT_SIZE

ACTIONS_EXTENDING_FLOW_PATH

flow actions that are extending the flow path.

ACTIONS_REDUCING_FLOW_PATH

flow actions that are shrinking/reducing the flow paths.

ACTIONS_CHANGING_FLOW_WITHOUT_CONFIRMATION

flow actions that are processed without the need to be confirmed.

FLOW_KEY_SEP

separator character between flow action/object and flow key

FLOW_ACTION_RE

regular expression detecting invalid characters in flow action string

FLOW_OBJECT_RE

regular expression detecting invalid characters in flow object string

HIDDEN_GLOBALS

tuple of global/module variable names that are hidden in global_variables()

PORTIONS_IMAGES

register of image files found in portions/packages at import time

PORTIONS_SOUNDS

register of sound files found in portions/packages at import time

USER_NAME_MAX_LEN

maximal length of a username/id (restricting user_id)

AppStateType

app state config variable type

EventKwargsType

change flow event kwargs type

ColorRGB

color red, green and blue parts

ColorRGBA

ink is rgb color and alpha

ColorOrInk

color or ink type

Functions

ellipse_polar_radius(ell_a, ell_b, radian)

calculate the radius from polar for the given ellipse and radian.

ensure_tap_kwargs_refs(init_kwargs, tap_widget)

ensure that the passed widget.__init__ kwargs dict contains a reference to itself within kwargs['tap_kwargs'].

flow_action(flow_id)

determine the action string of a flow_id.

flow_action_split(flow_id)

split flow id string into action part and the rest.

flow_change_confirmation_event_name(flow_id)

determine the name of the event method for the change confirmation of the passed flow_id.

flow_class_name(flow_id, name_suffix)

determine class name for the given flow id and class name suffix.

flow_key(flow_id)

return the key of a flow id.

flow_key_split(flow_id)

split flow id into action with object and flow key.

flow_object(flow_id)

determine the object string of the passed flow_id.

flow_path_id(flow_path[, path_index])

determine the flow id of the newest/last entry in the flow_path.

flow_path_strip(flow_path)

return copy of passed flow_path with all non-enter actions stripped from the end.

flow_popup_class_name(flow_id)

determine name of the Popup class for the given flow id.

id_of_flow(action[, obj, key])

create flow id string.

register_package_images()

call from module scope of the package to register/add image/img resources path.

register_package_sounds()

call from module scope of the package to register/add sound file resources.

replace_flow_action(flow_id, new_action)

replace action in given flow id.

update_tap_kwargs(widget[, popup_kwargs])

update or simulate widget's tap_kwargs property and return the updated dictionary (for kv rule of tap_kwargs).

Classes

MainAppBase(**console_app_kwargs)

abstract base class to implement a GUIApp-conform app class

APP_STATE_SECTION_NAME = 'aeAppState'

config section name to store app state

APP_STATE_VERSION_VAR_NAME = 'app_state_version'

config variable name to store the current application state version

COLOR_BLACK = [0.009, 0.006, 0.003, 1.0]

!= 0/1 to differentiate from framework pure black/white colors

THEME_DARK_BACKGROUND_COLOR = [0.009, 0.006, 0.003, 1.0]

dark theme background color in rgba(0.0 … 1.0)

THEME_DARK_FONT_COLOR = [0.999, 0.996, 0.993, 1.0]

dark theme font color in rgba(0.0 … 1.0)

THEME_LIGHT_BACKGROUND_COLOR = [0.999, 0.996, 0.993, 1.0]

light theme background color in rgba(0.0 … 1.0)

THEME_LIGHT_FONT_COLOR = [0.009, 0.006, 0.003, 1.0]

light theme font color in rgba(0.0 … 1.0)

MIN_FONT_SIZE = 15.0

minimum (s.a. min_font_size) and

MAX_FONT_SIZE = 99.0
ACTIONS_EXTENDING_FLOW_PATH = ['add', 'confirm', 'edit', 'enter', 'open', 'show', 'suggest']

flow actions that are extending the flow path.

ACTIONS_REDUCING_FLOW_PATH = ['close', 'leave']

flow actions that are shrinking/reducing the flow paths.

ACTIONS_CHANGING_FLOW_WITHOUT_CONFIRMATION = ['', 'enter', 'focus', 'leave', 'suggest']

flow actions that are processed without the need to be confirmed.

FLOW_KEY_SEP = ':'

separator character between flow action/object and flow key

FLOW_ACTION_RE = re.compile('[a-z0-9]+')

regular expression detecting invalid characters in flow action string

FLOW_OBJECT_RE = re.compile('[A-Za-z0-9_]+')

regular expression detecting invalid characters in flow object string

HIDDEN_GLOBALS = ('ABC', 'abstractmethod', '_add_base_globals', 'Any', '__builtins__', '__cached__', 'Callable', '_d_', 'Dict', '__doc__', '__file__', 'List', '__loader__', 'module_globals', '__name__', 'Optional', '__package__', '__path__', '__spec__', 'Tuple', 'Type', '__version__')

tuple of global/module variable names that are hidden in global_variables()

PORTIONS_IMAGES = {'add_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/add_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/add_item.png')], 'close_popup': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/close_popup.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/close_popup.png')], 'copy_node': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/copy_node.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/copy_node.png')], 'cut_node': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/cut_node.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/cut_node.png')], 'delete_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/delete_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/delete_item.png')], 'drag_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/drag_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/drag_item.png')], 'edit_font_size': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/enaml_app/img/edit_font_size.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/enaml_app/img/light_1/edit_font_size.png')], 'edit_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/edit_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/edit_item.png')], 'enter_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/enter_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/enter_item.png')], 'export_node': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/export_node.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/export_node.png')], 'filter_off': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/filter_off.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/filter_off.png')], 'filter_on': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/filter_on.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/filter_on.png')], 'font_size': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_user_prefs/img/light_1/font_size.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_user_prefs/img/font_size.png')], 'help_circled': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/help_circled.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/help_circled.png')], 'help_icon': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/help_icon.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/help_icon.png')], 'icon_view': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/icon_view.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/icon_view.png')], 'import_node': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/import_node.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/import_node.png')], 'leave_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/leave_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/leave_item.png')], 'list_view': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/list_view.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/list_view.png')], 'open_node_info': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/open_node_info.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/open_node_info.png')], 'open_user_preferences': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/enaml_app/img/open_user_preferences.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/enaml_app/img/light_1/open_user_preferences.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_user_prefs/img/open_user_preferences.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_user_prefs/img/light_1/open_user_preferences.png')], 'paste_node': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/paste_node.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/paste_node.png')], 'save_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/save_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/save_item.png')], 'send_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/send_item.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/send_item.png')], 'sideloading_activate': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_sideloading/img/sideloading_activate.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_sideloading/img/light_1/sideloading_activate.png')], 'tap_pointer': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/tap_pointer.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/img/light_1/tap_pointer.png')], 'vibration': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_user_prefs/img/vibration.png'), RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/kivy_user_prefs/img/light_1/vibration.png')]}

register of image files found in portions/packages at import time

PORTIONS_SOUNDS = {'added': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/added.wav')], 'debug_draw': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/debug_draw.wav')], 'debug_save': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/debug_save.wav')], 'deleted': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/deleted.wav')], 'edited': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/edited.wav')], 'enter_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/enter_item.wav')], 'error': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/error.wav')], 'filter_off': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/filter_off.wav')], 'filter_on': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/filter_on.wav')], 'leave_item': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/leave_item.wav')], 'touched': [RegisteredFile('/home/docs/checkouts/readthedocs.org/user_builds/ae/envs/stable/lib/python3.9/site-packages/ae/gui_app/snd/touched.wav')]}

register of sound files found in portions/packages at import time

USER_NAME_MAX_LEN = 12

maximal length of a username/id (restricting user_id)

AppStateType

app state config variable type

alias of Dict[str, Any]

EventKwargsType

change flow event kwargs type

alias of Dict[str, Any]

ColorRGB

color red, green and blue parts

alias of Union[Tuple[float, float, float], List[float]]

ColorRGBA

ink is rgb color and alpha

alias of Union[Tuple[float, float, float, float], List[float]]

ColorOrInk

color or ink type

alias of Union[Tuple[float, float, float], List[float], Tuple[float, float, float, float]]

ellipse_polar_radius(ell_a, ell_b, radian)[source]

calculate the radius from polar for the given ellipse and radian.

Parameters:
  • ell_a (float) – ellipse x-radius.

  • ell_b (float) – ellipse y-radius.

  • radian (float) – radian of angle.

Return type:

float

Returns:

ellipse radius at the angle specified by radian.

ensure_tap_kwargs_refs(init_kwargs, tap_widget)[source]

ensure that the passed widget.__init__ kwargs dict contains a reference to itself within kwargs[‘tap_kwargs’].

Parameters:
  • init_kwargs (Dict[str, Any]) – kwargs of the widgets __init__ method.

  • tap_widget (Any) – reference to the tap widget.

this alternative version is only 10 % faster but much less clean than the current implementation:

if 'tap_kwargs' not in init_kwargs:
    init_kwargs['tap_kwargs'] = {}
tap_kwargs = init_kwargs['tap_kwargs']

if 'tap_widget' not in tap_kwargs:
    tap_kwargs['tap_widget'] = tap_widget

if 'popup_kwargs' not in tap_kwargs:
    tap_kwargs['popup_kwargs'] = {}
popup_kwargs = tap_kwargs['popup_kwargs']
if 'opener' not in popup_kwargs:
    popup_kwargs['opener'] = tap_kwargs['tap_widget']
flow_action(flow_id)[source]

determine the action string of a flow_id.

Parameters:

flow_id (str) – flow id.

Return type:

str

Returns:

flow action string.

flow_action_split(flow_id)[source]

split flow id string into action part and the rest.

Parameters:

flow_id (str) – flow id.

Return type:

Tuple[str, str]

Returns:

tuple of (flow action string, flow obj and key string)

flow_change_confirmation_event_name(flow_id)[source]

determine the name of the event method for the change confirmation of the passed flow_id.

Parameters:

flow_id (str) – flow id.

Return type:

str

Returns:

tuple with 2 items containing the flow action and the object name (and id).

flow_class_name(flow_id, name_suffix)[source]

determine class name for the given flow id and class name suffix.

Parameters:
  • flow_id (str) – flow id.

  • name_suffix (str) – class name suffix.

Return type:

str

Returns:

name of the class. please note that the flow action open will not be added to the returned class name.

flow_key(flow_id)[source]

return the key of a flow id.

Parameters:

flow_id (str) – flow id string.

Return type:

str

Returns:

flow key string.

flow_key_split(flow_id)[source]

split flow id into action with object and flow key.

Parameters:

flow_id (str) – flow id to split.

Return type:

Tuple[str, str]

Returns:

tuple of (flow action and object string, flow key string).

flow_object(flow_id)[source]

determine the object string of the passed flow_id.

Parameters:

flow_id (str) – flow id.

Return type:

str

Returns:

flow object string.

flow_path_id(flow_path, path_index=-1)[source]

determine the flow id of the newest/last entry in the flow_path.

Parameters:
  • flow_path (List[str]) – flow path to get the flow id from.

  • path_index (int) – index in the flow_path.

Return type:

str

Returns:

flow id string or empty string if flow path is empty or index does not exist.

flow_path_strip(flow_path)[source]

return copy of passed flow_path with all non-enter actions stripped from the end.

Parameters:

flow_path (List[str]) – flow path list to strip.

Return type:

List[str]

Returns:

stripped flow path copy.

flow_popup_class_name(flow_id)[source]

determine name of the Popup class for the given flow id.

Parameters:

flow_id (str) – flow id.

Return type:

str

Returns:

name of the Popup class. please note that the action open will not be added to the returned class name.

id_of_flow(action, obj='', key='')[source]

create flow id string.

Parameters:
  • action (str) – flow action string.

  • obj (str) – flow object (defined by app project).

  • key (str) – flow index/item_id/field_id/… (defined by app project).

Return type:

str

Returns:

complete flow_id string.

register_package_images()[source]

call from module scope of the package to register/add image/img resources path.

no parameters needed because we use here stack_var() helper function to determine the module file path via the __file__ module variable of the caller module in the call stack. in this call we have to overwrite the default value (SKIPPED_MODULES) of the skip_modules parameter to not skip ae portions that are providing package resources and are listed in the SKIPPED_MODULES, like e.g. ae.gui_app and ae.gui_help (passing empty string ‘’ to overwrite default skip list).

register_package_sounds()[source]

call from module scope of the package to register/add sound file resources.

no parameters needed because we use here stack_var() helper function to determine the module file path via the __file__ module variable of the caller module in the call stack. in this call we have to overwrite the default value (SKIPPED_MODULES) of the skip_modules parameter to not skip ae portions that are providing package resources and are listed in the SKIPPED_MODULES, like e.g. ae.gui_app ae.gui_help (passing empty string ‘’ to overwrite default skip list).

replace_flow_action(flow_id, new_action)[source]

replace action in given flow id.

Parameters:
  • flow_id (str) – flow id.

  • new_action (str) – action to be set/replaced within passed flow id.

Returns:

flow id with new action and object/key from passed flow id.

update_tap_kwargs(widget, popup_kwargs=None, **tap_kwargs)[source]

update or simulate widget’s tap_kwargs property and return the updated dictionary (for kv rule of tap_kwargs).

Parameters:
  • widget (Any) – widget with tap_kwargs property to be updated.

  • popup_kwargs (Optional[Dict[str, Any]]) – dict with items to update popup_kwargs key of tap_kwargs

  • tap_kwargs – additional tap_kwargs items to update.

Return type:

Dict[str, Any]

Returns:

class MainAppBase(**console_app_kwargs)[source]

Bases: ConsoleApp, ABC

abstract base class to implement a GUIApp-conform app class

app_state_version: int = 0

version number of the app state variables in <config>.ini

flow_id: str = ''

id of the current app flow (entered by the app user)

flow_id_ink: Union[Tuple[float, float, float], List[float], Tuple[float, float, float, float]] = [0.99, 0.99, 0.69, 0.69]

rgba color for flow id / drag&drop node placeholder

flow_path_ink: Union[Tuple[float, float, float], List[float], Tuple[float, float, float, float]] = [0.99, 0.99, 0.39, 0.48]

rgba color for flow_path/drag&drop item placeholder

font_size: float = 21.0

font size used toolbar and flow screens

lang_code: str = ''

optional language code (e.g. ‘es_ES’ for Spanish)

light_theme: bool = False

True=light theme/background, False=dark theme

selected_item_ink: Union[Tuple[float, float, float], List[float], Tuple[float, float, float, float]] = [0.69, 1.0, 0.39, 0.18]

rgba color for list items (selected)

unselected_item_ink: Union[Tuple[float, float, float], List[float], Tuple[float, float, float, float]] = [0.39, 0.39, 0.39, 0.18]

rgba color for list items (unselected)

sound_volume: float = 0.12

sound volume of current app (0.0=mute, 1.0=max)

vibration_volume: float = 0.3

vibration volume of current app (0.0=mute, 1.0=max)

win_rectangle: tuple = (0, 0, 1920, 1080)

window coordinates (x, y, width, height)

framework_app: Any = None

app class instance of the used GUI framework

framework_win: Any = None

window instance of the used GUI framework

framework_root: Any = None

app root layout widget

image_files: Optional[FilesRegister] = None

image/icon files

sound_files: Optional[FilesRegister] = None

sound/audio files

__init__(**console_app_kwargs)[source]

create instance of app class.

Parameters:

console_app_kwargs – kwargs to be passed to the __init__ method of ConsoleApp.

_exit_code: int

init by stop_app() and passed onto OS by run_app()

_last_focus_flow_id: str

id of the last valid focused window/widget/item/context

flow_path: List[str]

list of flow ids, reflecting recent user actions

_start_event_loop: Optional[Callable]

callable to start event loop of GUI framework

_stop_event_loop: Optional[Callable]

callable to start event loop of GUI framework

_init_default_user_cfg_vars()[source]

init user default config variables.

override this method to add module-/app-specific config vars that can be set individually per user.

abstract init_app(framework_app_class=None)[source]

initialize framework app instance and root window/layout, return GUI event loop start/stop methods.

Parameters:

framework_app_class (Optional[Any]) – class to create app instance (optionally extended by app project).

Return type:

Tuple[Optional[Callable], Optional[Callable]]

Returns:

tuple of two callable, the 1st to start and the 2nd to stop/exit the GUI event loop.

app_state_keys()[source]

determine current config variable names/keys of the app state section APP_STATE_SECTION_NAME.

Return type:

Tuple[str, ...]

Returns:

tuple of all app state item keys (config variable names).

static backup_config_resources()[source]

backup config files and image/sound/translations resources to {ado}<now_str>.

config files are collected from {ado}, {usr} or {cwd} (the first found file name only - see/sync-with ae.console.ConsoleApp.add_cfg_files()).

resources are copied from {ado} or {cwd} (only the first found resources root path).

Return type:

str

change_app_state(app_state_name, state_value, send_event=True, old_name='')[source]

change app state to state_value in self.<app_state_name> and app_states dict.

Parameters:
  • app_state_name (str) – name of the app state to change.

  • state_value (Any) – new value of the app state to change.

  • send_event (bool) – pass False to prevent send/call of the main_app.on_<app_state_name> event.

  • old_name (str) – pass to add state to the main config file: old state name to rename/migrate or UNSET to only add a new app state variable with the name specified in app_state_name.

change_observable(name, value, is_app_state=False)[source]

change observable attribute/member/property in framework_app instance (and shadow copy in main app).

Parameters:
  • name (str) – name of the observable attribute/member or key of an observable dict property.

  • value (Any) – new value of the observable.

  • is_app_state (bool) – pass True for an app state observable.

change_flow(new_flow_id, **event_kwargs)[source]

try to change/switch the current flow id to the value passed in new_flow_id.

Parameters:
  • new_flow_id (str) – new flow id (maybe overwritten by flow change confirmation event handlers by assigning a flow id to event_kwargs[‘flow_id’]).

  • event_kwargs

    optional args to pass additional data or info onto and from the flow change confirmation event handler.

    the following keys are currently supported/implemented by this module/portion (additional keys can be added by the modules/apps using this method):

    • changed_event_name: optional main app event method name to be called if the flow got confirmed and changed.

    • count: optional number used to render a pluralized help text for this flow change (this number gets also passed to the help text formatter by/in change_flow()).

    • edit_widget: optional widget instance for edit/input.

    • flow_id: process flow_path as specified by the new_flow_id argument, but then overwrite this flow id with this event arg value to set flow_id.

    • popup_kwargs: optional dict passed to the Popup __init__ method, like e.g. dict(opener=opener_widget_of_popup, data=…).

    • popups_to_close: optional sequence of widgets to be closed by this method after flow change got confirmed.

    • ’reset_last_focus_flow_id’: pass True to reset the last focus flow id, pass False or None to ignore the last focus id (and not use to set flow id) or pass a flow id string value to change the last focus flow id to the passed value.

    • tap_widget: optional tapped button widget instance (initiating this flow change).

    some of these keys get specified directly on the call of this method, e.g. via tap_kwargs or tap_kwargs, where others get added by the flow change confirmation handlers/callbacks.

Return type:

bool

Returns:

True if flow got confirmed by a declared custom flow change confirmation event handler (either event method or Popup class) of the app and changed accordingly, else False.

some flow actions are handled internally independent of the return value of a custom event handler, like e.g. ‘enter’ or ‘leave’ will always extend or reduce the flow path and the action ‘focus’ will give the indexed widget the input focus (these exceptions are configurable via ACTIONS_CHANGING_FLOW_WITHOUT_CONFIRMATION).

static class_by_name(class_name)[source]

search class name in framework modules as well as in app main.py to return class object.

Parameters:

class_name (str) – name of the class.

Return type:

Optional[Type]

Returns:

class object with the specified class name or UNSET if not found.

static dpi_factor()[source]

dpi scaling factor - override if the used GUI framework supports dpi scaling.

Return type:

float

close_popups(classes=())[source]

close all opened popups (starting with the foremost popup).

Parameters:

classes (tuple) – optional class filter - if not passed then only the first foremost widgets underneath the app win with an open method will be closed. pass tuple to restrict found popup widgets to certain classes. like e.g. by passing (Popup, DropDown, FlowPopup) to get all popups of an app (in Kivy use Factory.WidgetClass if widget is declared only in kv lang).

find_image(image_name, height=32.0, light_theme=True)[source]

find best fitting image in img app folder (see also img_file() for easier usage).

Parameters:
  • image_name (str) – name of the image (file name without extension).

  • height (float) – preferred height of the image/icon.

  • light_theme (bool) – preferred theme (dark/light) of the image.

Return type:

Optional[RegisteredFile]

Returns:

image file object (RegisteredFile/CachedFile) if found else None.

find_sound(sound_name)[source]

find sound by name.

Parameters:

sound_name (str) – name of the sound to search for.

Return type:

Optional[RegisteredFile]

Returns:

cached sound file object (RegisteredFile/CachedFile) if sound name was found else None.

find_widget(match)[source]

search the widget tree returning the first matching widget in reversed z-order (top-/foremost first).

Parameters:

match (Callable[[Any], bool]) – callable called with the widget as argument, returning True if widget matches.

Return type:

Optional[Any]

Returns:

first found widget in reversed z-order (top-most widget first).

flow_path_action(flow_path=None, path_index=-1)[source]

determine the action of the last (newest) entry in the flow_path.

Parameters:
  • flow_path (Optional[List[str]]) – optional flow path to get the flow action from (default=self.flow_path).

  • path_index (int) – optional index in the flow_path (default=-1).

Return type:

str

Returns:

flow action string or empty string if flow path is empty or index does not exist.

global_variables(**patches)[source]

determine generic/most-needed global variables to evaluate expressions/macros.

Parameters:

patches – dict of variable names and values to add/replace on top of generic globals.

Return type:

Dict[str, Any]

Returns:

dict of global variables patched with patches.

img_file(image_name, font_size=None, light_theme=None)[source]

shortcutting find_image() method w/o bound property to get image file path.

Parameters:
  • image_name (str) – image name (file name stem).

  • font_size (Optional[float]) – optional font size in pixels.

  • light_theme (Optional[bool]) – optional theme (True=light, False=dark).

Return type:

str

Returns:

file path of image file or empty string if image file not found.

key_press_from_framework(modifiers, key)[source]

dispatch key press event, coming normalized from the UI framework.

Parameters:
  • modifiers (str) – modifier keys.

  • key (str) – key character.

Return type:

bool

Returns:

True if key got consumed/used else False.

load_app_states()[source]

load application state from the config files to prepare app.run_app

load_images()[source]

load images from app folder img.

load_sounds()[source]

load audio sounds from app folder snd.

load_translations(lang_code)[source]

load translation texts for the passed language code.

Parameters:

lang_code (str) – the new language code to be set (passed as flow key). empty on first app run/start.

mix_background_ink()[source]

remix background ink if one of the basic back colours change.

on_app_build()[source]

default/fallback flow change confirmation event handler.

on_app_exit()[source]

default/fallback flow change confirmation event handler.

on_app_init()[source]

default/fallback flow change confirmation event handler.

on_app_quit()[source]

default/fallback flow change confirmation event handler.

on_app_run()[source]

default/fallback flow change confirmation event handler.

on_app_started()[source]

app initialization event - the last one on app startup.

on_debug_level_change(level_name, _event_kwargs)[source]

debug level app state change flow change confirmation event handler.

Parameters:
  • level_name (str) – the new debug level name to be set (passed as flow key).

  • _event_kwargs (Dict[str, Any]) – unused event kwargs.

Return type:

bool

Returns:

True to confirm the debug level change.

on_flow_change(flow_id, event_kwargs)[source]

checking if exists a Popup class for the new flow and if yes then open it.

Parameters:
  • flow_id (str) – new flow id.

  • event_kwargs (Dict[str, Any]) – optional event kwargs; the optional item with the key popup_kwargs will be passed onto the __init__ method of the found Popup class.

Return type:

bool

Returns:

True if Popup class was found and displayed.

this method is mainly used as the last fallback clicked flow change confirmation event handler of a FlowButton.

on_flow_id_ink()[source]

redirect flow id back ink app state color change event handler to actualize mixed_back_ink.

on_flow_path_ink()[source]

redirect flow path back ink app state color change event handler to actualize mixed_back_ink.

static on_flow_popup_close(_flow_key, _event_kwargs)[source]

default popup close handler of FlowPopup widget, ensuring update of flow_path.

Parameters:
  • _flow_key (str) – unused flow key.

  • _event_kwargs (Dict[str, Any]) – unused popup args.

Return type:

bool

Returns:

always returning True.

on_lang_code_change(lang_code, _event_kwargs)[source]

language app state change flow change confirmation event handler.

Parameters:
  • lang_code (str) – the new language code to be set (passed as flow key). empty on first app run/start.

  • _event_kwargs (Dict[str, Any]) – unused event kwargs.

Return type:

bool

Returns:

True to confirm the language change.

on_light_theme_change(_flow_key, event_kwargs)[source]

app theme app state change flow change confirmation event handler.

Parameters:
  • _flow_key (str) – flow key.

  • event_kwargs (Dict[str, Any]) – event kwargs with key ‘light_theme’ containing True|False for light|dark theme.

Return type:

bool

Returns:

True to confirm change of flow id.

on_selected_item_ink()[source]

redirect selected item back ink app state color change event handler to actualize mixed_back_ink.

on_unselected_item_ink()[source]

redirect unselected item back ink app state color change event handler to actualize mixed_back_ink.

on_user_add(user_name, event_kwargs)[source]

called on close of UserNameEditorPopup to check user input and create/register the current os user.

Parameters:
  • user_name (str) – new user id.

  • event_kwargs (Dict[str, Any]) – optionally pass True in the unique_user_name key to prevent duplicate usernames.

Return type:

bool

Returns:

True if user got registered else False.

play_beep()[source]

make a short beep sound, should be overwritten by GUI framework.

play_sound(sound_name)[source]

play audio/sound file, should be overwritten by GUI framework.

Parameters:

sound_name (str) – name of the sound to play.

play_vibrate(pattern=(0.0, 0.09, 0.21, 0.3, 0.09, 0.09, 0.21, 0.09))[source]

play vibrate pattern, should be overwritten by GUI framework.

Parameters:

pattern (Tuple) – optional tuple of pause and vibrate time sequence - use error pattern if not passed.

open_popup(popup_class, **popup_kwargs)[source]

open Popup/DropDown, calling the open/show method of the instance created from the passed popup class.

Parameters:
  • popup_class (Type) – class of the Popup/DropDown widget/window.

  • popup_kwargs – args to instantiate and show/open the popup.

Return type:

Any

Returns:

created and displayed/opened popup class instance.

Hint

overwrite this method if framework is using different method to open popup window or if a widget in the Popup/DropDown need to get the input focus.

popups_opened(classes=())[source]

determine all popup-like container widgets that are currently opened.

Parameters:

classes (Tuple) – optional class filter - if not passed then only the widgets underneath win/root with an open method will be added. pass tuple to restrict found popup widgets to certain classes. like e.g. by passing (Popup, DropDown, FlowPopup) to get all popups of an ae/Kivy app (in Kivy use Factory.WidgetClass if widget is declared only in kv lang).

Return type:

List

Returns:

list of the foremost opened/visible popup class instances (children of the app window), matching the classes or having an open method, ordered by their z-coordinate (most front widget first).

retrieve_app_states()[source]

determine the state of a running app from the main app instance and return it as dict.

Return type:

Dict[str, Any]

Returns:

dict with all app states available in the config files.

run_app()[source]

startup main and framework applications.

save_app_states()[source]

save app state in config file.

Return type:

str

Returns:

empty string if app status could be saved into config files else error message.

setup_app_states(app_states)[source]

put app state variables into main app instance to prepare framework app.run_app.

Parameters:

app_states (Dict[str, Any]) – dict of app states.

show_message(message, title='', is_error=True)[source]

display (error) message popup to the user.

Parameters:
  • message (str) – message string to display.

  • title (str) – title of message box.

  • is_error (bool) – pass False to not emit error tone/vibration.

stop_app(exit_code=0)[source]

quit this application.

Parameters:

exit_code (int) – optional exit code.

upgraded_config_app_state_version()[source]

determine app state version of an app upgrade.

Return type:

int

Returns:

value of app state variable APP_STATE_VERSION_VAR_NAME if the app got upgraded (and has a config file from a previous app installation), else 0.

widget_by_attribute(att_name, att_value)[source]

determine the first (top-most) widget having the passed attribute name and value.

Parameters:
  • att_name (str) – name of the attribute of the searched widget.

  • att_value (str) – attribute value of the searched widget.

Return type:

Optional[Any]

Returns:

widget that has the specified attribute with the specified value or None if not found.

widget_by_flow_id(flow_id)[source]

determine the first (top-most) widget having the passed flow_id.

Parameters:

flow_id (str) – flow id value of the searched widget’s tap_flow_id/focus_flow_id attribute.

Return type:

Optional[Any]

Returns:

widget that has a tap_flow_id/focus_flow_id attribute with the value of the passed flow id or None if not found.

widget_by_app_state_name(app_state_name)[source]

determine the first (top-most) widget having the passed app state name (app_state_name).

Parameters:

app_state_name (str) – app state name of the widget’s app_state_name attribute.

Return type:

Optional[Any]

Returns:

widget that has a app_state_name attribute with the passed app state name or None if not found.

widget_children(wid, only_visible=False)[source]

determine the children of widget or its container (if exists) in z-order (top-/foremost first).

Parameters:
  • wid (Any) – widget to determine the children from.

  • only_visible (bool) – pass True to only return visible widgets.

Return type:

List

Returns:

list of children widgets of the passed widget.

static widget_pos(wid)[source]

return the absolute window x and y position of the passed widget.

Parameters:

wid – widget to determine the position of.

Return type:

Tuple[float, float]

Returns:

tuple of x and y screen/window coordinate.

widgets_enclosing_rectangle(widgets)[source]

calculate the minimum bounding rectangle all the passed widgets.

Parameters:

widgets (Union[list, tuple]) – list/tuple of widgets to determine the minimum bounding rectangle for.

Return type:

Tuple[float, float, float, float]

Returns:

tuple of floats with the x, y, width, height values of the bounding rectangle.

static widget_size(wid)[source]

return the size (width and height) in pixels of the passed widget.

Parameters:

wid – widget to determine the size of.

Return type:

Tuple[float, float]

Returns:

tuple of width and height in pixels.

static widget_visible(wid)[source]

determine if the passed widget is visible (has width and height and (visibility or opacity) set).

Parameters:

wid (Any) – widget to determine visibility of.

Return type:

bool

Returns:

True if widget is visible (or visibility cannot be determined), False if hidden.

win_pos_size_change(*win_pos_size)[source]

screen resize handler called on window resize or when app will exit/stop via closed event.

Parameters:

win_pos_size – window geometry/coordinates: x, y, width, height.