By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,691 Members | 1,143 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,691 IT Pros & Developers. It's quick & easy.

Tkinter Canvas/Grid question

P: n/a
Is there a simple way of causing the size of a canvas to change as the
window is resized when using the Grid geometry manager? Setting
sticky='NESW', as in the following code, doesn't work though the
documentation for Grid seems to imply that it should: "sticky If a
slave's cell is larger than its requested dimensions, this option may be
used to position (or stretch) the slave within its cell. ... The sticky
option subsumes the combination of anchor and fill that is used by
pack". Or is there something wrong with my code?

Thanks,
Gary Richardson

from Tkinter import *

class Test(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
frame = Frame(parent)
self.canvas = Canvas(frame, bg='white' , width=300, height=100)
self.canvas.grid(row=0, column=0, sticky='NESW')
frame.grid()

root = Tk()
Test(root)
root.mainloop()

Jul 18 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Hi Gary
from Tkinter import *

class Test(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
frame = Frame(parent)
There is some confusion here: self *is* the frame, no need or use to make
another....
self.canvas = Canvas(frame, bg='white' , width=300, height=100)
There is some trick needed here: add:
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.canvas.grid(row=0, column=0, sticky='NESW')
frame.grid()

This packs the frame to the parent, so it limits the size of your frame in
any case
I should recommend pack in this place (which is possible, because it's
another frame)

Altogether it shall look as follows and work fine:

def __init__(self, parent):
Frame.__init__(self, parent)
self.pack(fill=BOTH,expand=1)

self.canvas = Canvas(self, bg='white' , width=300, height=100)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.canvas.grid(row=0, column=0, sticky='nesw')

Jul 18 '05 #2

P: n/a
To expand on Michael Peuser's response, I'll explain a little more. The
grid first calculates the size requested by each item to find the
requested size for each row and column. When there are no rowspans,
the requested size for a row is the maximum of the requested sizes for
any item in that row. The same holds when talking about columns, their
weights and their widths.

Then, when there is too much or too little space, the difference is
split up among the rows according to their weight. The default weight
for a row is 0. Let total_weight be the sum of the weight of each row
with a widget, and diff be the number of pixels difference between the
height of the frame and the sum of the requested heights of its rows. If
total_weight is 0, then all rows get their requested height. Otherwise,
each row gets diff*row_weight/total_weight, with something done about
the rounding errors.

That's why the short answer to set the weight of row and column 0 to 1
works.

The other problem you may run into (I haven't run your code, but with
many levels of widget present, this may be a problem) is that each
level of the widget tree between this one containing the canvas, and the
Toplevel() or Tk() above it, must also be configured so that they will
expand to consume any extra available space. Otherwise, the condition
"when there is too much or too little space" can't be true, because the
widget won't be given a larger size than it requested.

Jeff

Jul 18 '05 #3

P: n/a

"Jeff Epler" <je****@unpythonic.net>

Thank you for the comprehensive explanations you gave I was to lazy to do
;-)
In addition I should like to point out a chapter from Nancy Walsh's book
"Learning Perl/Tk" where one can find a lot of information about the
different geometry managers (no prejudices against Perl I hope?)
http://www.oreilly.com/catalog/lperl...pter/ch02.html
The other problem you may run into (I haven't run your code, but with
many levels of widget present, this may be a problem) is that each
level of the widget tree between this one containing the canvas, and the
Toplevel() or Tk() above it, must also be configured so that they will
expand to consume any extra available space


This had been one of the problems, so I suggested to use an appropriate
paramtrized pack on the higher level for simplicity.

Kindly
Michael P
Jul 18 '05 #4

P: n/a
"Michael Peuser" <mp*****@web.de> wrote in message
news:bj*************@news.t-online.com...
[snip]
Michael, Jeff,

Thanks for your replies. I made the changes indicated above and the resizing
works just fine now. I'm still puzzled as to why pack() would be used with
the frame and grid() used with the canvas, and other widgets, I suppose. I
was under the impression that only a single geometry manager should be used
in a program. I guess the rule is: a single geometry manager must be used
within a frame and its descendants. Is that correct?

Thanks,
Gary Richardson


Jul 18 '05 #5

P: n/a

"Gary Richardson" <ga***@fidalgo.net>
Michael, Jeff,

Thanks for your replies. I made the changes indicated above and the resizing works just fine now. I'm still puzzled as to why pack() would be used with
the frame and grid() used with the canvas, and other widgets.
No, no! I just use pack() because it is much simpler and you made no
constraints as to how to show the frame in the toplevel.. There is a lot of
useful information in that chapter from Nacy Welsh's book

...... was under the impression that only a single geometry manager should be used in a program. I guess the rule is: a single geometry manager must be used
within a frame and its descendants. Is that correct?


Nearly. You can freely choose the g.m. in EVERY frame (but then stick to it
in THAT frame)

Kindly
Michael P


Jul 18 '05 #6

P: n/a
> "Gary Richardson" <ga***@fidalgo.net>
Michael, Jeff,

Thanks for your replies. I made the changes indicated above and the

resizing
works just fine now. I'm still puzzled as to why pack() would be used with
the frame and grid() used with the canvas, and other widgets.


You can manage any widget with any geometry manager. (You can even grid
a button inside of a label, but god knows why you'd want to)

Sometimes you must use "grid" to get proper layout. For instance, if
you want to create a scrolled item (canvas or text) with horizontal and
vertical scrollbars, this is the only sane way to do it.

Jul 18 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.