Advanced Input¶
Warning
This section contains advanced input techniques which may lead to buggy code in your program if they are not used correctly.
The default technique to get user input is already described in UIScreen, and that should be the preferred way to obtain user input. However, if the default technique is not enough for your situation then read the text below to find out how to implement custom input.
Input handler classes¶
Input handler classes are classes created to obtain user input. If required
InputHandler
can block an application until user input is received.
This class can be instantiated everywhere in the code and used to ask for user input:
handler = InputHandler()
handler.get_input("Shut up and give me your input:")
handler.wait_for_input()
if handler.input_successful:
user_input = handler.value
The InputHandler.wait_on_input()
method will block code processing until user input is
received. Input should always be checked before processing.
In case some other work needs to be done before user input is received, then pass
a callback to the constructor of the InputHandler
class and do not use
the InputHandler.wait_on_input()
method. However, the callback is using
the event loop so it won’t be called until event loop
processing is active. If concurrent input is used then this
callback might never get called!
If what a user types must not be displayed, then the PasswordInputHandler
class
should be used. It shares most of its implementation with the InputHandler
but overrides
how to obtain the code. For more info look at the PasswordInputHandler
class
documentation.
Concurrent input¶
Concurrent input is something which should be avoided. It drags unexpected behavior into an application and is hard to debug. However, there could be an instance when user input is required immediately, even when an application is already waiting for other input.
By default, every attempt for concurrent input will raise an exception and kill the application to
prevent unexpected behavior. In order to allow for concurrent input, the
InputHandler.skip_concurrency_check
property must be set. After this property is disabled
for the InputHandler
instance, then the handler instance then it can support
concurrent input.
The last registered concurrent input will result in dropping all other waiting inputs – even other
waiting inputs with InputHandler.skip_concurrency_check
will be dropped. The dropped
waiting inputs will get a failed input signal to unblock InputHandler.wait_on_input()
methods.
Creating a custom InputHandler¶
If the InputHandler
class or the PasswordInputHandler
class is not enough,
developers can create their own handler. The structure of an input handler is based on two
classes. First is a handler itself, and second is the request object it creates.
The handler class is used as an interface for the rest of the application. It also creates
the requester instance. The requester object is a low-level implementation of obtaining user input.
The requester object has to have the get_input
method and should contain the text_prompt
method. The get_input
method is called in a separate thread and should prompt the user for
input. The text_prompt
method is required mainly for concurrent input, and it returns
a string representation of the prompt.
For more details, please look at the implementation of the InputHandler
class.
InputHandler class¶
-
class
simpleline.input.input_handler.
InputHandler
(callback=None, source=None)¶ -
create_thread_object
(prompt)¶ Create thread object containing all the information how to get user input.
Returns: Instance of class inherited from simpleline.input.InputThread.
-
get_input
(prompt)¶ Use prompt to ask for user input and wait (non-blocking) on user input.
This is an asynchronous call. If you want to wait for user input then use the wait_on_input method. If you want to get results asynchronously then register callback in constructor or by the set_callback method.
Check if user input was already received can be done by the input_received method call.
Parameters: prompt (String or Prompt instance.) – Ask user what you want to get. Returns: User input. Return type: str
-
input_received
()¶ Was user input already received?
Returns: True if yes, False otherwise.
-
input_successful
()¶ Was input successful?
Returns: bool
-
set_callback
(callback)¶ Set a callback to get user input asynchronously.
Parameters: callback (Method with 1 argument which is user input: def cb(user_input)) – Callback called when user write their input.
-
skip_concurrency_check
¶ Is this InputHandler skipping concurrency check?
:returns bool
-
source
¶ Get source of this input.
Returns: Anything probably UIScreen.
-
value
¶ Return user input.
Returns: String or None if no is input received.
-
wait_on_input
()¶ Blocks execution till the user input is received.
Events will works as expected during this blocking.
Please check the input_successful method to test the input.
-
PasswordInputHandler class¶
-
class
simpleline.input.input_handler.
PasswordInputHandler
(callback=None, source=None)¶ -
create_thread_object
(prompt)¶ Return PasswordInputThread for getting user password.
-
get_input
(prompt)¶ Use prompt to ask for user input and wait (non-blocking) on user input.
This is an asynchronous call. If you want to wait for user input then use the wait_on_input method. If you want to get results asynchronously then register callback in constructor or by the set_callback method.
Check if user input was already received can be done by the input_received method call.
Parameters: prompt (String or Prompt instance.) – Ask user what you want to get. Returns: User input. Return type: str
-
input_received
()¶ Was user input already received?
Returns: True if yes, False otherwise.
-
input_successful
()¶ Was input successful?
Returns: bool
-
set_callback
(callback)¶ Set a callback to get user input asynchronously.
Parameters: callback (Method with 1 argument which is user input: def cb(user_input)) – Callback called when user write their input.
-
set_pass_func
(getpass_func)¶ Set a function for getting passwords.
-
skip_concurrency_check
¶ Is this InputHandler skipping concurrency check?
:returns bool
-
source
¶ Get source of this input.
Returns: Anything probably UIScreen.
-
value
¶ Return user input.
Returns: String or None if no is input received.
-
wait_on_input
()¶ Blocks execution till the user input is received.
Events will works as expected during this blocking.
Please check the input_successful method to test the input.
-