Tkinter question

Rotwang sg552 at hotmail.co.uk
Fri Apr 23 07:58:03 EDT 2010


eb303 wrote:
> On Apr 22, 5:55 pm, Rotwang <sg... at hotmail.co.uk> wrote:
>> 
>> [...]
>> 
> 
> From my experience, mixing Tkinter with threads is a bad idea. As most
> GUI toolkits, it really doesn't like to be manipulated from different
> threads, so you might end up getting weird problems or even crashes.
> 
> By the way, did you try to remove the line out.mainloop() from your
> 'draw' function?

I didn't. How do I get Python to display the draw window, other than by 
using mainloop()?


> This is the line that blocks the IDLE GUI, since it
> initiates a secondary event loop that will only exit when you do a
> out.quit(), so that might be a solution.
> 
>> BTW, another problem: whenever I call a widget.quit() method, the widget
>> in question crashes. IDLE carries on working but the widget window stays
>> there, not responding, and if I tell my OS to kill it then IDLE
>> restarts. Is this a bug? I'm using Windows 7 and Python 2.6.4.
> 
> The 'quit' method just exits the mainloop. It doesn't destroy the
> widget. So if your application doesn't actually exit, the widget will
> just stay there. If you want to destroy the it too, you have to call
> explicitely widget.destroy().

That worked like a charm, thanks!

Here's another problem I've run into today: I've just added a bit of 
code so that it's possible to resize the draw window and the contents 
will be resized automatically. The method now looks something like this:

out = Tkinter.Tk()
slave = Tkinter.Canvas(out, width = wh[0], height = wh[1])
slave.grid()
	# I put the canvas widget inside a tk widget instead of just
	# using the former because I want keypresses to do things, and
	# it doesn't seem to be possible to bind keyboard events to a
	# canvas
# draw something
slave.pack()

def resize(b):
	wh[:] = [b.width, b.height]
	slave.config(width = wh[0], height = wh[1])
	# resize the contents of slave

out.bind('<Configure>', resize)
out.mainloop()


The trouble is, when I call the method the window it spawns slowly grows 
larger, until I move or resize it myself by grabbing one of the edges; 
after this everything works as intended. If I add the line "print wh" 
after "wh[:] = [b.width, b.height]", the output looks like this (the 
default value of wh is [640,480]:

[644, 484]
[648, 488]
[648, 488]
[648, 488]
[652, 492]
[652, 492]
[652, 492]
[656, 496]
[656, 496]
[656, 496]
[660, 500]
etc.

My only guess as to why this is happening is that Tkinter is resizing 
out to be 4 pixels wider and taller than slave, and the line 
"slave.config(...)" consequently leads to resize being called again. But 
this doesn't explain why it stops happening when I resize the window 
intentionally, nor why the window apparently only gets larger every 
third time resize is called. The problem goes away if I replace "wh[:] = 
[b.width, b.height]" with

	wh[:] = [b.width - 4, b.height - 4]

but this seems like a rather ad-hoc and ugly solution, and I'd rather 
understand what's going on. Can anyone help?



More information about the Python-list mailing list