1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
#!/usr/bin/env python
"""
An example that demonstrates how inputhooks can be used in prompt-toolkit.
An inputhook is a callback that an eventloop calls when it's idle. For
instance, readline calls `PyOS_InputHook`. This allows us to do other work in
the same thread, while waiting for input. Important however is that we give the
control back to prompt-toolkit when some input is ready to be processed.
There are two ways to know when input is ready. One way is to poll
`InputHookContext.input_is_ready()`. Another way is to check for
`InputHookContext.fileno()` to be ready. In this example we do the latter.
"""
import gobject
import gtk
from pygments.lexers.python import PythonLexer
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.patch_stdout import patch_stdout
from prompt_toolkit.shortcuts import PromptSession
def hello_world_window():
"""
Create a GTK window with one 'Hello world' button.
"""
# Create a new window.
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_border_width(50)
# Create a new button with the label "Hello World".
button = gtk.Button("Hello World")
window.add(button)
# Clicking the button prints some text.
def clicked(data):
print("Button clicked!")
button.connect("clicked", clicked)
# Display the window.
button.show()
window.show()
def inputhook(context):
"""
When the eventloop of prompt-toolkit is idle, call this inputhook.
This will run the GTK main loop until the file descriptor
`context.fileno()` becomes ready.
:param context: An `InputHookContext` instance.
"""
def _main_quit(*a, **kw):
gtk.main_quit()
return False
gobject.io_add_watch(context.fileno(), gobject.IO_IN, _main_quit)
gtk.main()
def main():
# Create user interface.
hello_world_window()
# Enable threading in GTK. (Otherwise, GTK will keep the GIL.)
gtk.gdk.threads_init()
# Read input from the command line, using an event loop with this hook.
# We use `patch_stdout`, because clicking the button will print something;
# and that should print nicely 'above' the input line.
with patch_stdout():
session = PromptSession(
"Python >>> ", inputhook=inputhook, lexer=PygmentsLexer(PythonLexer)
)
result = session.prompt()
print(f"You said: {result}")
if __name__ == "__main__":
main()
|