Imagination: Simpler than PySimpleGUI and python tkinter: talking directly to tcl/tk
Even though FreeSimpleGUI is a good approach to simpler tk/tcl binding in python : we can do better, especially if your linux distro split the python package and you don’t have access to tkinter. I am watching you debian, splitting ALL packages and breaking them including … tcl from tk (what a crime).
Under debian this stunt requires you to install tk :
apt install tk8.6
How hard is it when tcl/tk is installed to do GUI programming in tk without tkinter?
Well, it’s fairly easy, first and foremost coders are coders, they code in whatever language. If you do code in one language you can’t do docker, simple sysadmin tasks (shell), compile C extensions (make syntax) or web applications (HTML + javascript). Hence, learning more than one language is part of doing python applications.
How hard is codinig in tcl/tk natively?
Fairly easy: it’s difficulty is a little above lua, and way below perl thanks to the absence of references.
What value tcl have ?
It’s still used in domain specific field such as VLSI (Very Large Scale Integration of electronic component).
So here is the plan : we are gonna do an application that do the math in python which is perfect for expressing complex math in more readable way than tcl and push all the GUI to the tk interpreter (albeit wish).
We are gonna make a simple wall clock … and all tcl commands are injected to tcl through the puts function.
#!/usr/bin/env python from subprocess import Popen, PIPE from time import sleep, time, localtime # let's talk to tk/tcl directly through p.stdin p = Popen(['wish'], stdin=PIPE) def puts(s): for l in s.split("\n"): p.stdin.write((l + "\n").encode()) p.stdin.flush() WIDTH=HEIGHT=400 puts(f""" canvas .c -width {WIDTH} -height {HEIGHT} -bg white pack .c . configure -background "white" """) # Constant are CAPitalized in python by convention from cmath import pi as PI, e as E ORIG=complex(WIDTH/2, HEIGHT/2) # correcting python notations j => I I = complex("j") rad_per_sec = 2.0 * PI /60.0 rad_per_min = rad_per_sec / 60 rad_per_hour = rad_per_min / 12 origin_vector_hand = WIDTH/2 * I size_of_sec_hand = .9 size_of_min_hand = .8 size_of_hour_hand = .65 rot_sec = lambda sec : -E ** (I * sec * rad_per_sec ) rot_min = lambda min : -E ** (I * min * rad_per_min ) rot_hour = lambda hour : -E ** (I * hour * rad_per_hour ) to_real = lambda c1,c2 : "%f %f %f %f" % (c1.real,c1.imag,c2.real, c2.imag) for n in range(60): direction= origin_vector_hand * rot_sec(n) start=.9 if n%5 else .85 puts(f".c create line {to_real(ORIG+start*direction,ORIG+.95*direction)}") sleep(.1) diff_offset_in_sec = (time() % (24*3600)) - \ localtime()[3]*3600 -localtime()[4] * 60.0 \ - localtime()[5] while True: t = time() s= t%60 m = m_in_sec = t%(60 * 60) h = h_in_sec = (t- diff_offset_in_sec)%(24*60*60) puts(".c delete second") puts(".c delete minute") puts(".c delete hour") c0=ORIG+ -.1 * origin_vector_hand * rot_sec(s) c1=ORIG+ size_of_sec_hand * origin_vector_hand * rot_sec(s) puts( f".c create line {to_real(c0,c1)} -tag second -fill blue -smooth true") c1=ORIG+size_of_min_hand * origin_vector_hand * rot_min(m) puts(f".c create line {to_real(ORIG, c1)} -tag minute -fill green -smooth true") c1=ORIG+size_of_hour_hand * origin_vector_hand * rot_hour(h) puts(f".c create line {to_real(ORIG,c1)} -tag hour -fill red -smooth true") sleep(.1)
Next time as a bonus, I’m gonna do something tkinter cannot do: bidirectional communications (REP/REQ pattern).