[Pythonmac-SIG] pythonmac & GUI

Andrew C. Greenberg werdna@gate.net
Fri, 30 Oct 1998 23:55:53 -0500


Bob Savage writes:

>I have been slowly learning Python, but have yet to do anything with a GUI.
>I tried Tkinter a few times, but it doesn't seem to work reliably for me. I
>tried running the 'Hello GUI world' code from the Lutz tome, and I ended up
>not being able to quit from the Python IDE (the menubar changes to reflect
>the mini app, but 'quit' does not work, so all I can do is force quit??)
>The same thing happened on two different computers, BTW.

Lately, I've been looking for a decent vehicle for facilitating GUI
"dabbling" on the Macintosh, as I have found myself hacking together a
bunch of special purpose "one to throw away" applications for my family of
late.  As is my wont, I return to python as a wonderful vehicle for that
sort of thing, lamenting the difficulty in producing a passable GUI.

Each time I do this, I go back to, but usually abandon Python for more
"traditional" development environments, never quite satisfied with the
GUI's I've been able to generate with relatively minimal effort.  Tkinter
seemed too fragile, and the framework seemed to require too much work for
the bang compared, say, to the more powerful Codewarrier frameworks.
JPython held my interest for quite a while this time (what a really
wonderful and elegant hack!), but then, awt being what it is made me long
for the virtues of MPW.

This time I stuck with Tkinter a bit longer than usual, and seem to have
managed to make it "stick.".  Although I found the menu mechanisms
EXTREMELY fragile at first, crashing and burning and forcing hard-quits WAY
too often, I eventually found a protocol that worked reliably and wrapped
defensively from that fragility in a stable application framework.  The
reward seemed worthwhile: I now am able to put together straightforward
simple applications without thinking too hard about Tkinter's fragility,
enjoying the virtues of Python without the fears of runnning into the next
breakpoint.  If there is interest, I will be pleased to post that
quasi-"solution" once I am a little less embarassed by the general state of
the code.

Digging into all the Tcl/Tk documentation yielded one neat reward that
might be of interest to some in the MacPython Sig:  I found a reference in
the Macintosh Tk 8.0 FAQ to an "undocumented" facility to generate windows
with window styles other than the standard zoomDocProc in the Macintosh
version of Wish.  It turns out that a call to Tk command

	undocumented1 style window styledescriptor

before a window is first displayed will yield a window using an alternative
document style.  This trick is best illustrated with the following script,
which produces a listbox you can click to view the next style.  I haven't
been able to change the style for a window that has already been displayed,
however, and remain curious if that is possible.  Accordingly, the present
script has to spawn a new window, self-destructing the present window to
achieve the desired effect.  Moreover, I am unable to change the style of
the root window.

Of course the virtue of Tkinter is generally its machine independence.
Still, its nice to make Mac programs that look and behave more like Mac
programs, particularly when I am just prototyping GUI's to "make one to
throw away."

-----

import Tkinter,sys,string

styles = [
	'documentProc', 'dBoxProc', 'plainDBox', 'altDBoxProc',
'movableDBoxProc',
	'zoomDocProc', 'rDocProc', 'floatProc', 'floatZoomProc',
'floatSideProc',
	'floatSideZoomProc'
]

class FunnyStyleWindow(Tkinter.Toplevel):
	def __init__(self,master=None,style='documentProc'):
		self.master = master
		Tkinter.Toplevel.__init__(self,master)
		self.withdraw()
		self.mac_style(style)
		self.geometry('+100+100')
		self.title(style)
		self.resizable(0,0)
		self.lb = Tkinter.Listbox(self)
		for i in styles:
			self.lb.insert(Tkinter.END,i)
		self.lb.bind('<ButtonRelease>',self.handleclick)
		self.lb.pack()
		self.deiconify()

	def mac_style(self,string):
		return self.tk.call('unsupported1','style', self._w, string)

	def handleclick(self,*args):
		e = args[0]
		lb = e.widget
		idx = lb.index('@'+repr(e.x)+','+repr(e.y))
		newstyle = lb.get(idx)
		FunnyStyleWindow(self.master,newstyle)
		self.destroy()


root = Tkinter.Tk()
FunnyStyleWindow()
root.mainloop()