UIScreen

The base class for creating a new screen. UIScreen is used for any user interaction. UIScreen uses containers and widgets to present information to a user, and the UIScreen.input() method to get input from a user to an application. Screens are pushed to the screen stack, which are then used to communicate with a user. See the screen handling section to find out more.

The methods UIScreen.redraw(), UIScreen.close(), UIScreen.emit() and UIScreen.create_and_emit() are asynchronous. These methods will create a signal which is passed to the event loop for later processing.

Beware, methods UIScreen.redraw() and UIScreen.close() can lead to unexpected behavior when multiple instances of these signals are emitted (methods are called multiple times). This can even crash your application.

Lifecycle

Every UIScreen has a distinct lifecycle: uninitialized, initialized, draw, process input and closed. If the screen has already been initialized (it was drawn to a monitor) and will be shown again, then the screen skips the uninitialized stage. The screen can cycle between draw and process input stages by calling the UIScreen.redraw() method after processing user input.

In case UIScreen.redraw() won’t be called and no new screen is pushed, or this screen wasn’t closed, then an application will stay in an infinite loop waiting for something to happen. This is correct behavior because there could be something in an event loop which will call UIScreen.redraw() later.

Rendering widgets

The UIScreen.refresh() method is the most important part of the UIScreen. It contains preparations for rendering (creating widgets and adding them to containers). The UIScreen.refresh() method will be called before anything is drawn on a monitor.

The UIScreen.window attribute, which is the WindowContainer instance, contains all items (widgets, containers) which are to be rendered by the screen. A new WindowContainer is created in the UIScreen.refresh() method for every screen redraw. The UIScreen.title attribute is passed to the WindowContainer.title property, and a developer can add widgets and other containers to present items to a user by calling WindowContainer.add() or WindowContainer.add_with_separator(). Multiple items can be added by calling these methods repeatedly.

When everything is prepared properly in the UIScreen.refresh() method, it needs to be drawn on the monitor for a user. This is handled by the UIScreen.show_all() method. This method works automatically, but it could also be useful for a developer, especially when the screen will not process input. In this case, the UIScreen.input() method is not called at all. Developers can override this method and call the parent class’s UIScreen.show_all(), which will handle drawing the screen and any additional processing.

Redrawing the screen can be invoked by the UIScreen.redraw() method. However, this is not processed immediately. Instead it will be added to the event loop and processed later, when the loop is idle. Beware, after every redraw call the input is processed if not disabled, so if multiple redraw signals are emitted, than the application will crash.

The UIScreen.redraw() method is also invoked when a screen is pushed to the stack.

User input processing

If the screen shouldn’t process user input, the UIScreen.input_required property needs to be set to False. True is the default value for this property.

After everything is printed to a monitor, the UIScreen will wait for user input. For this purpose there is UIScreen.input(), which is called when a user passes string input to a screen. The screen needs to react upon user input and return one of the options from the InputState enum or the user input string.

To accept the user input, InputState.PROCESSED, InputState.PROCESSED_AND_REDRAW or InputState.PROCESSED_AND_CLOSE should be returned. Addition to accepting user input the InputState.PROCESSED_AND_REDRAW value will also redraw active screen and InputState.PROCESSED_AND_CLOSE will close active screen. However, if InputState.PROCESSED is used then the developer is responsible for not ending in frozen application. The UIScreen.refresh() or the UIScreen.close() methods must be called manually.

In case the user input is invalid, the InputState.DISCARDED value should be returned. This will reject the user input and wait for another attempt. The UIScreen.refresh method will be called after 5 rejections and show the screen output again.

If the user input string is returned it will be checked for options of the Prompt instance which can either close the screen, refresh the screen (this will call UIScreen.refresh()) or quit the application.

Closing screens

There are several ways to close a screen. One is by calling UIScreen.close() or by pressing c to continue (with the default Prompt class). When the screen is closed the next screen on the stack will be shown. A screen can also be replaced. Then the original screen is removed from the stack without closing a screen. If a reaction on closing a screen is required then the UIScreen.closed() callback should be overridden.

Beware, when calling UIScreen.close() multiple times it will close multiple screens. This is because the close signal will always close the top screen on the screen stack.

UIScreen class

class simpleline.render.screen.UIScreen(title=None, screen_height=30)

Base class representing one TUI Screen.

Shares some API with anaconda’s GUI to make it easy for devs to create similar UI with the familiar API.

close()

Emit signal to close this screen.

Add CloseScreenSignal to the event loop.

closed()

Callback when this screen is closed.

connect(signal, callback, data=None)

Connect this class method with given signal.

Parameters:
  • signal (class based on simpleline.event_loop.AbstractSignal) – signal class which you want to connect
  • callback (func(event_message, data)) – the callback function
  • data (Anything) – Data you want to pass to the callback
create_and_emit(signal)

Create the signal and emit it.

This is basically shortcut for calling self.create_signal and self.emit.

create_signal(signal_class, priority=0)

Create signal instance usable in the emit method.

Parameters:
  • signal_class (class based on simpleline.event_loop.AbstractSignal) – signal you want to use
  • priority (int) – priority of the signal; please look on the simpleline.event_loop.AbstractSignal.priority for further info
emit(signal)

Emit the signal.

This will add signal to the event loop.

Parameters:signal (instance of class based on simpleline.event_loop.AbstractSignal) – signal to emit
get_input_with_error_check(args)

Get user input and redraw if user add too many invalid inputs.

This method should be used only by ScreenScheduler.

Parameters:args (Anything.) – Arguments passed in when scheduling this screen.
get_user_input(message, hidden=False)

Get immediately input from the user.

Use this with cautious. Never call this in middle of rendering or when other input is already waiting. It is recommended to use self.input_required instead.

Parameters:
  • message (str) – Message prompt for the user.
  • hidden (bool) – Do not echo user input (password typing).
hide_user_input

Hide typed user input.

This is main solution how to ask for password.

Returns:True if user input should be hidden. False otherwise (default).
input(args, key)

Method called to process input. If the input is not handled here, return it.

Parameters:
  • key (str) – input string to process
  • args (anything) – optional argument passed from switch_screen calls
Returns:

return simpleline.render.InputState.PROCESSED if key was handled, simpleline.render.InputState.DISCARDED if the screen should not process input on the scheduler and key if you want it to.

Return type:

simpleline.render.InputState enum | str

input_required

Return if the screen requires input.

no_separator

Should we print separator for this screen?

Returns:True to print separator before this screen (default). False do not print separator.
password_func

Get password function.

This is function with one argument to get password from command line.

prompt(args=None)

Return the text to be shown as prompt or handle the prompt and return None.

Parameters:args (anything) – optional argument passed from switch_screen calls
Returns:returns an instance of Prompt with text to be shown next to the prompt for input or None to skip further input processing
Return type:Prompt instance|None
redraw()

Emit signal to initiate draw.

Add RenderScreenSignal to the event loop.

refresh(args=None)

Method which prepares the content desired on the screen to self.window.

Parameters:args (anything) – optional argument passed from switch_screen calls
screen_ready

This screen is ready for use.

setup(args)

Do additional setup right before this screen is used.

It is mandatory to call this ancestor method in the child class to set ready status.

Parameters:args (array of values) – arguments for the setup
Returns:whether this screen should be scheduled or not
Return type:bool
show_all()

Print WindowContainer in self.window with all its content.

title

Screen title.

window

Return WindowContainer instance.

InputState enum

class simpleline.render.screen.InputState

An enumeration.

DISCARDED = 0
PROCESSED = 1
PROCESSED_AND_CLOSE = 3
PROCESSED_AND_REDRAW = 2