Skip to content

sredmond/popup-console

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Popup Console in Python

Navigating the command line prompt can be difficult for students who are new to programming. IDLE is a great GUI-based program that shows a command prompt side-by-side with a Python file, but that restricts users to IDLE.

This project provides a popup console in Tk for Python programs.

Installation

TODO(sredmond): Write an installation from PyPI.

Usage

By default, calling the setup() method will create a popup console window and redirect stdin and stdout to that window.

import console
console.setup()

print('Hello, world!')
name = input('What is your name?')
print('Hello', name)

This redirection happens at the level of sys.stdin and sys.stdout.

import console
console.setup()

import sys
print(sys.stdin)  # => ConsoleIO object.

The original stdin and stdout file objects can be accessed via console.original_stdin and console.original_stdout.

Better Python: Being More Explicit

This behind-the-scenes implicit magic isn't very Pythonic. It's a reasonable default for our use case because we're hiding lots from our students, but

import console
popup = console.create(capture=False)

popup.write()
popup.

Creating Several Popup Consoles

With the default behavior, the popup console is spawned in another process so that Tk can listen for text input events concurrently to our potentially-slow Python code. However, you might not want this behavior. To just instantiate the actual Console widget:

import tkinter as tk
from console.widget import ConsoleWidget

root = tk.Tk()
widget = ConsoleWidget(root)
widget.pack()

There are two ways to write to the widget. Synchronously:

widget.print('Hello, world!')
widget.write('Hello, world!\n')

Asynchronously:

??

There is only one way to read from the widget.

name = widget.input('What is your name?')
entry = widget.readline()

Boring Technical Details for the Curious

  • When stdout is captured, print gets curried with flush=True by default.

How does it work?

From the perspective of the console, it's a text widget that maintains a buffered input and a buffered output.

  • The student calls print

  • One way or another, this calls the write method of a subclass of TextIOBase

  • this then writes out to subprocess' stdin.

  • subprocess is busy-looping on checking stdin

  • subprocess sees stdin and tells a tk window to print it

  • tk window updates a tk text widget w/ new info.

  • the student calls input

  • one way or another, this calls readline on a subclass of textiobase

  • this blocks on reading a line from a buffer of inbound lines.

  • where does this buffer come from?

    • student for each subprocess spawned, a watchdog thread is spawned that monitors the subprocesses stdout, consumes it, and adds it to a buffer in memory.
    • subprocess prints a message to stdout
    • text entry, upon receiving an ENTER character, synchronously calls something like stdout.

perhaps this last one is better in reverse

  • student hits ENTER
  • tk text widget captures the entered line(s) and writes to some textiostream
  • wrapper is busy looping checking the internal buffer for content, and upon finding some, writes to sp' stdout
  • this unblocks a watchdog thread in the client process, which immediately consumes the content and buffers it.
  • advanced - tell it to spawn a thread for

Notes

Don't forget to link simpio as a test dependency!

What to do...

console is pretty good here! popup console python

CONSOLE: on main thread, create a window with a text widget. on an event loop, consume from stdin and print to console if anything is there. otherwise, update and update idletasks.

upon registering a \n character, also write to stdout.

possibly: launch a background thread to just consume from stdin to avoid OS pipe buffer lockup. probably not though.

CLIENT: launch this CONSOLE in a subprocess and capture its stdin and stdout. to print to console, write to stdin. to read from console, blocking monitor its stdout.

real downside. goes through OS-level encoding? unless Python's wrappers do the "right thing"

OTHER USE:

Text Widget to be added to another existing Tk application. can be given output by someone else (e.g. something like a console.write or console.print call) maintains its own list of inputs. can be asked for input (blocking). that call awaits the UI providing some value.??

  • remove ALL conceptual overhead
  • probably not sublime + terminal

About

Graphical Popup Console in TK

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages