Tkinter question

Rotwang sg552 at hotmail.co.uk
Fri Apr 23 15:44:01 EDT 2010


eb303 wrote:
> On Apr 23, 1:58 pm, Rotwang <sg... at hotmail.co.uk> wrote:
>> 
>> [...]
>>
>> I didn't. How do I get Python to display the draw window, other than by
>> using mainloop()?
> 
> Well, mainloop doesn't actually display anything. It's just the event
> loop for tk. So since you run your program within IDLE, there is
> already one running. What does it do if you delete the mainloop()
> line? Doesn't your window appear at all?

No.


>> [...]
>> 
>> 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()
> 
> (Hope this line is a mistake: gridding *and* packing slave will
> probably result in tk thinking for ages how it should display it in
> its parent…)

Not a mistake so much as a symptom of my inept, cargo-cult approach to 
programming. Needless to say you're correct that it shouldn't be there, 
though taking it out doesn't give a noticeable improvement in 
performance (perhaps because the canvas is the only thing there so 
there's no conflict).


>> def resize(b):
>>         wh[:] = [b.width, b.height]
>>         slave.config(width = wh[0], height = wh[1])
>>         # resize the contents of slave
>>
> 
> You don't need at all to resize the slave explicitely. You should do
> the following:
> - Tell 'out' that its first row and first column should resize
> themselves when the window is resized by doing:
> out.grid_rowconfigure(1, weight=1)
> out.grid_columnconfigure(1, weight=1)
> - Make sure slave is actually put in the cell in first row and column,
> and that all its sides will stick to the cell borders:
> slave.grid(row=1, column=1, sticky='nswe')
> 
> If you do that, the slave.config in the resize function shouldn't be
> needed anymore.

Indeed! That works great.


>> out.bind('<Configure>', resize)
> 
> If using the grid options, better do a slave.bind(…) here, which will
> call the binding when the canvas is resized, which is obvioulsy when
> you want to update its contents.

Right, though before you suggested making the sides of the canvas 
sticky, resizing the window didn't reconfigure slave.


>> [...] 
>> 
> You get the size for the outer window and apply it to the canvas
> inside it. Since the canvas has a border which is 2 pixels wide by
> default, this resizes the window containing it to take this border
> into account. So your binding is called again, and so on… But using
> the options to grid described above, there should never be any need to
> resize the canvas explicitely.

Thanks very much for your help.



More information about the Python-list mailing list