Re: Feasibility of console based (non-Gui) Tkinter app which can accept keypresses?
Hi All thanks for the comments and confirmation that this is not really possible in a Tkinter environment. I had thought of using ncurses but was shying clear of learning about another set of widgets etc. just now. The output of the simulator is simple enough that it could just accept simple keystrokes for control, and every second or so there will be an output string saying what is happening - a sort of concatenation of the various output widgets in the Tkinter-based version. I have hoped to keep this text view so similar to the Tkinter one that it was using the same mechanisms (after(), Tk keyevents etc). Instead I think I will just write a simple mainloop() which is 'inspired by' Tkinter. I could then look at adding ncurses as a third alternative. Thanks again J^n -- https://mail.python.org/mailman/listinfo/python-list
Re: Feasibility of console based (non-Gui) Tkinter app which can accept keypresses?
On 7/11/2018 10:09 AM, jkn wrote: Hi All This is more of a Tkinter question rather than a python one, I think, but anyway... I have a Python simulator program with a Model-View_Controller architecture. I have written the View part using Tkinter in the first instance; later I plan to use Qt. However I also want to be able to offer an alternative of a console-only operation. So I have a variant View with the beginnings of this. Naturally I want to keep this as similar as possible to my Tkinter-based view. I had thought that I had seen a guide somewhere to using Tk/Tkinter in a non-GUI form. The only reason I can think of to use tkinter in a text application is to its multiple simultaneous timer loops. I don't seem to be able to track this down now, but I have at least been successful in hiding ('withdrawing') the main Frame, and running a main loop. At the end of this response is an experiment in driving text-output coroutines with tkinter, where I did as you say above. The bit which I am now stumbling on is trying to bind key events to my view, and I am wondering if this actually makes any sense. In the absence of a GUI I want to accept keypresses to control the simulation. But in a console app I will have no visible or in focus window, and therefore at what level would any keys be bound? Not at the widget level, nor the frame, and I am not sure if the the root makes sense either. You cannot use the tkinter widget bind command. If you can use curses or something to move the cursor around the screen, you can emulate widgets and key binding with characters, an after loop, and key handlers. +---+ | Find: _ | | Ignore case [ ] Up ( ) Down ( )| +---+ keyhandle = entry def keyhit(): if kbhit(): # Windows, someone else gave linux equivalent keyhandle(getch()) root.after(50, keyhit) root.after(50, keyhit) # Start key polling keyhandler is initially entry, which echoes printable chars and moves cursor to Ignore case [_] on tab (assuming you have gui box do the same) and changes keyhandle to check. Check treats [space] as a left click and call whatever the gui checkbutton command is. Ditto for radio and the binding to radiobuttons. So I am looking for confirmation of this, and/or whether there is any way of running a Tkinter application in 'console' mode, running a main loop and both outputting data and accepting, and acting on, key presses. Brett's countdown.py (see link below) implements an event loop using time.sleep and a priority queue. A 'keyhit loop could be added to that, but the result is still to text apps. --- """https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/ How the heck does async/await work in Python 3.5? Bret Cannon """ import datetime import types from time import perf_counter from tkinter import Tk class SleepingLoop: """An event loop focused on delaying execution of coroutines. Think of this as being like asyncio.BaseEventLoop/curio.Kernel. """ def __init__(self, *coros): self.coros = coros self.waiting = set() self.root = Tk() self.root.withdraw() def callback(self, coro): try: # It's time to resume the coroutine. seconds = coro.send(perf_counter()) self.root.after(int(seconds * 1000), self.callback, coro) except StopIteration: # The coroutine is done. self.waiting.remove(coro) if not self.waiting: self.root.quit() def run_until_complete(self): # Start all the coroutines (async generators) for coro in self.coros: self.waiting.add(coro) seconds = coro.send(None) self.root.after(int(seconds * 1000), self.callback, coro) self.root.mainloop() @types.coroutine def sleep(seconds): """Pause a coroutine for the specified number of seconds. Think of this as being like asyncio.sleep()/curio.sleep(). """ now = perf_counter() actual = yield seconds # Resume the execution stack, sending back how long we actually waited. return actual - now async def countdown(label, length, *, delay=0): """Countdown a launch for `length` seconds, waiting `delay` seconds. This is what a user would typically write. """ print(label, 'waiting', delay, 'seconds before starting countdown') delta = await sleep(delay) print(label, 'starting after waiting', delta) while length: print(label, 'T-minus', length) waited = await sleep(1) length -= 1 print(label, 'lift-off!') def main(): """Start the event loop, counting down 3 separate launches. This is what a user would typically write. """ loop = SleepingLoop(countdown('A', 5, delay=2), countdown(' B', 3, delay=2), countdown(' C', 4, delay=1))
Re: Feasibility of console based (non-Gui) Tkinter app which can accept keypresses?
You may want to check Urwid instead. 2018-07-11 16:22 GMT-03:00 Jim Lee : > On 07/11/18 07:09, jkn wrote: > >> Hi All >> This is more of a Tkinter question rather than a python one, I >> think, but >> anyway... >> >> I have a Python simulator program with a Model-View_Controller >> architecture. I >> have written the View part using Tkinter in the first instance; later I >> plan >> to use Qt. >> >> However I also want to be able to offer an alternative of a console-only >> operation. So I have a variant View with the beginnings of this. >> >> Naturally I want to keep this as similar as possible to my Tkinter-based >> view. I >> had thought that I had seen a guide somewhere to using Tk/Tkinter in a >> non-GUI >> form. I don't seem to be able to track this down now, but I have at least >> been >> successful in hiding ('withdrawing') the main Frame, and running a main >> loop. >> >> The bit which I am now stumbling on is trying to bind key events to my >> view, >> and I am wondering if this actually makes any sense. In the absence of a >> GUI I >> want to accept keypresses to control the simulation. But in a console app >> I will >> have no visible or in focus window, and therefore at what level would any >> keys be bound? Not at the widget level, nor the frame, and I am not sure >> if the >> the root makes sense either. >> >> So I am looking for confirmation of this, and/or whether there is any way >> of >> running a Tkinter application in 'console' mode, running a main loop and >> both outputting data and accepting, and acting on, key presses. >> >> Thanks >> J^n >> >> > I think the general answer is no, but beyond that, it may be worth > considering switching from an MVC architecture to a simpler > frontend-backend, especially if you intend to add a third interface (Qt): > > MVC w/Tk, console, Qt: > > Seven conceptual modules (three controllers, three views, one model) > Two abstraction layers (controller<->model, model<->view) > > Frontend-backend w/Tk, console, Qt: > > Four conceptual modules (three frontends, one backend) > One abstraction layer (frontend<->backend) > > -Jim > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: Feasibility of console based (non-Gui) Tkinter app which can accept keypresses?
On 07/11/18 07:09, jkn wrote: Hi All This is more of a Tkinter question rather than a python one, I think, but anyway... I have a Python simulator program with a Model-View_Controller architecture. I have written the View part using Tkinter in the first instance; later I plan to use Qt. However I also want to be able to offer an alternative of a console-only operation. So I have a variant View with the beginnings of this. Naturally I want to keep this as similar as possible to my Tkinter-based view. I had thought that I had seen a guide somewhere to using Tk/Tkinter in a non-GUI form. I don't seem to be able to track this down now, but I have at least been successful in hiding ('withdrawing') the main Frame, and running a main loop. The bit which I am now stumbling on is trying to bind key events to my view, and I am wondering if this actually makes any sense. In the absence of a GUI I want to accept keypresses to control the simulation. But in a console app I will have no visible or in focus window, and therefore at what level would any keys be bound? Not at the widget level, nor the frame, and I am not sure if the the root makes sense either. So I am looking for confirmation of this, and/or whether there is any way of running a Tkinter application in 'console' mode, running a main loop and both outputting data and accepting, and acting on, key presses. Thanks J^n I think the general answer is no, but beyond that, it may be worth considering switching from an MVC architecture to a simpler frontend-backend, especially if you intend to add a third interface (Qt): MVC w/Tk, console, Qt: Seven conceptual modules (three controllers, three views, one model) Two abstraction layers (controller<->model, model<->view) Frontend-backend w/Tk, console, Qt: Four conceptual modules (three frontends, one backend) One abstraction layer (frontend<->backend) -Jim -- https://mail.python.org/mailman/listinfo/python-list
Re: Feasibility of console based (non-Gui) Tkinter app which can accept keypresses?
On Thu, Jul 12, 2018 at 12:09 AM, jkn wrote: > Hi All > This is more of a Tkinter question rather than a python one, I think, but > anyway... > > I have a Python simulator program with a Model-View_Controller architecture. I > have written the View part using Tkinter in the first instance; later I plan > to use Qt. > > However I also want to be able to offer an alternative of a console-only > operation. So I have a variant View with the beginnings of this. > > Naturally I want to keep this as similar as possible to my Tkinter-based > view. I > had thought that I had seen a guide somewhere to using Tk/Tkinter in a non-GUI > form. I don't seem to be able to track this down now, but I have at least been > successful in hiding ('withdrawing') the main Frame, and running a main loop. > > The bit which I am now stumbling on is trying to bind key events to my view, > and I am wondering if this actually makes any sense. In the absence of a GUI I > want to accept keypresses to control the simulation. But in a console app I > will > have no visible or in focus window, and therefore at what level would any > keys be bound? Not at the widget level, nor the frame, and I am not sure if > the > the root makes sense either. ISTM you want to have a variant Controller as well, to allow a completely different way of managing the display. The easiest and cleanest UI is probably a line-based console input command system, where the user would type something and hit enter, and you receive that using input(). That also plays nicely with input redirection, allowing you to control your program from another program. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Feasibility of console based (non-Gui) Tkinter app which can accept keypresses?
On 07/11/2018 08:09 AM, jkn wrote: > So I am looking for confirmation of this, and/or whether there is any way of > running a Tkinter application in 'console' mode, running a main loop and> > both outputting data and accepting, and acting on, key presses. So far as I know, no this isn't possible, especially on any Unix system where Tk is getting events from the graphical windowing system, which doesn't exist in a console. NCurses is the usual go-to library for console applications that need to get keyboard events. -- https://mail.python.org/mailman/listinfo/python-list