Skip to content

Instantly share code, notes, and snippets.

@Lucretiel
Last active July 30, 2022 03:58
Show Gist options
  • Save Lucretiel/e7d9a50b7b1960a56a1c to your computer and use it in GitHub Desktop.
Save Lucretiel/e7d9a50b7b1960a56a1c to your computer and use it in GitHub Desktop.
from tkinter import *
import asyncio
from functools import wraps
import websockets
def runloop(func):
'''
This decorator converts a coroutine into a function which, when called,
runs the underlying coroutine to completion in the asyncio event loop.
'''
func = asyncio.coroutine(func)
@wraps(func)
def wrapper(*args, **kwargs):
return asyncio.get_event_loop().run_until_complete(func(*args, **kwargs))
return wrapper
@asyncio.coroutine
def run_tk(root, interval=0.05):
'''
Run a tkinter app in an asyncio event loop.
'''
try:
while True:
root.update()
yield from asyncio.sleep(interval)
except TclError as e:
if "application has been destroyed" not in e.args[0]:
raise
@asyncio.coroutine
def listen_websocket(url):
'''
Connect to a websocket url, then print messages received on the connection
until closed by the server.
'''
ws = yield from websockets.connect(url)
while True:
msg = yield from ws.recv()
if msg is None:
break
print(msg)
@runloop
def main():
root = Tk()
entry = Entry(root)
entry.grid()
def spawn_ws_listener():
return asyncio.async(listen_websocket(entry.get()))
Button(root, text='Print', command=spawn_ws_listener).grid()
yield from run_tk(root)
if __name__ == "__main__":
main()
@rudasoftware
Copy link

rudasoftware commented Jul 9, 2019

Right. I just wanted to see how tkinter runs "as intended" in the MacOS environment.

Yep, that's a goofy-looking unfortunate graph, haha.

@chmedly
Copy link

chmedly commented Jul 9, 2019

I think I've figured it out. This page at tkdocs tells of bad things that happen with the elderly version of Tcl/Tk included with MacOs.
https://tkdocs.com/tutorial/install.html
They say to not use this version (typically 8.5) but instead to install the latest 8.6 (8.6.9 now). But, if you install Python with homebrew, there is currently no easy way to point it to a newly installed version of Tk. At this point in my research, the only way to get the updated Tcl/Tk to work with Python3 is to install Python without homebrew. Anyway, I've run the tk_sync_demo.py code (that I posted previously) on a Mac with Python 3.7.3 AND Tk version 8.6. Memory runs flatline. So, it looks like my intention of simplifying cross platform support by using a built-in library for the GUI (instead of PyQt5) is not as flawless as I had hoped.
tk_sync_demo_Tcl86

@rudasoftware
Copy link

Aww man, that's a bummer. Glad you found the culprit, though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment