473,387 Members | 1,619 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Tkinter grid layout

Hi there,

I've got a tree control in Tkinter (using the ESRF Tree module) but I
can't get it to layout how I want it.

I'd like to have it so that it streches north/south (anchored to the top
and bottom), is of a fixed width and is anchored to the left hand side.
Here's my code (its derived from one of the examples from the ESRF web
site):

class MainWindow(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.document = # new DOM document
self.create_site_list()

def create_site_list(self):
self.list_model = ListModel(self.document)
# ListModel class returns the DOM outline as a simple Python data
structure

self.site_list = Tree.Tree(master=self,\
root_id="root",\
root_label="Site",\
get_contents_callback=self.get_list_item,\
# get_list_item uses the list_model to build list nodes
width=300)

self.site_list.grid(row=0, column=0, sticky=N+SW)

self.grid_rowconfigure(0, weight=1)

vsb = Scrollbar(self, orient=VERTICAL)
vsb.grid(row=0, column=1, sticky=NS)
self.site_list.configure(yscrollcommand=vsb.set)
vsb.configure(command=self.site_list.yview)

hsb = Scrollbar(self, orient=HORIZONTAL)
hsb.grid(row=1, column=0, sticky=EW+S)
self.site_list.configure(xscrollcommand=hsb.set)
hsb.configure(command=self.site_list.xview)

self.site_list.focus_set()
This code makes it centred in the east/west direction and a constant
height anchored to the top. I guess its the sticky values I need to play
with (?) but I can't find the right combination. I've given the code
with the ones that seem logically correct (to me!)

I expect this is probably quite trivial for someone who knows what
they're doing.

Any ideas?

Cheers,
Richard
Jul 21 '05 #1
6 8220
On Wed, 06 Jul 2005 11:44:55 +0100, Richard Lewis <ri**********@fastmail.co.uk> wrote:
Hi there,

I've got a tree control in Tkinter (using the ESRF Tree module) but I
can't get it to layout how I want it.

I'd like to have it so that it streches north/south (anchored to the top
and bottom), is of a fixed width and is anchored to the left hand side.
Here's my code (its derived from one of the examples from the ESRF web
site):

class MainWindow(Frame):

[snip code]

First of all, it is not a good idea to make your so-called window inherit from Frame: a Frame is not a window in tk, but a generic container. Creating a Frame without a container window will automatically initialize the tk toolkit, creating a default window which will become the default parent for widgets where you don't specify one. According to the well-known "explicit is better than implicit" principle, if a MainWindow instance are actually the main window for your application, you'd really better inherit from the Tkinter class for the main window, which is Tk. Doing it this way has a lot of advantages over what you do; for example, if you later have to create a menu bar for your application, you will be able to do it in the MainWindow class. If you inherit from Frame, you won't get any access to the actual window, so you won't be able to create a menu in it.

This may seems to be unrelated to your problem, but it's not: by creating a Frame, you introduce one more unneeded container. So, in some code you don't show here, you have to insert the MainWindow instance into its parent window via a call to its pack or grid method. Since the code you show seems to be correct, I guess the problem is in this call to pack or grid, which probably does not tell the Frame how to behave when its parent window is resized, causing it to get the default behaviour, which is "do nothing at all".

To be sure this actually is the problem, try to replace the line:
Frame.__init__(self, master)
in MainWindow.__init__ by:
Frame.__init__(self, master, bg='blue', bd=2)
This way, a blue border will appear around the frame, allowing you to see how it grows.
Then run your application, and resize the window. You should see that the frame does not grow when the window grows, explaining why your tree deos not grow (in fact, it would grow if its container did; but its container doesn't...)

So you should either make your MainWindow class inherit from Tk, which eliminates the unneeded container and the problems it may cause, or make sure the pack or grid on your MainWindow instance actually tells the container to grow with its container. With pack, it's quite easy: just do myWindow.pack(fill=BOTH, expand=1). With grid, it's a bit more complicated, since you will have to configure the grid on the container.

But basically, my advice would be:
- Never make your windows inherit from Frame; make them inherit from Tk for the main window or from Toplevel for all other ones
- When you have resize problems, always check the whole widget hierarchy from the actual window down to the widget showing the problem. The cause is very often not on the widget itself, but on one of its containers.

HTH
--
python -c "print ''.join([chr(154 - ord(c)) for c in 'U(17zX(%,5.zmz5(17;8(%,5.Z65\'*9--56l7+-'])"
Jul 21 '05 #2

On Wed, 06 Jul 2005 17:36:01 +0200, "Eric Brunel"
<er*********@despammed.com> said:
On Wed, 06 Jul 2005 11:44:55 +0100, Richard Lewis
<ri**********@fastmail.co.uk> wrote:
Hi there,

I've got a tree control in Tkinter (using the ESRF Tree module) but I
can't get it to layout how I want it.

I'd like to have it so that it streches north/south (anchored to the top
and bottom), is of a fixed width and is anchored to the left hand side.
Here's my code (its derived from one of the examples from the ESRF web
site):

class MainWindow(Frame):

[snip code]

First of all, it is not a good idea to make your so-called window inherit
from Frame: a Frame is not a window in tk, but a generic container.
[....]
But basically, my advice would be:
- Never make your windows inherit from Frame; make them inherit from Tk
for the main window or from Toplevel for all other ones
- When you have resize problems, always check the whole widget hierarchy
from the actual window down to the widget showing the problem. The cause
is very often not on the widget itself, but on one of its containers.

And very sound advice it turns out to be! I've changed my MainWindow
class to inherit from Tk and now all the layout works fine.

Thanks very much for your help!

Cheers,
Richard
Jul 21 '05 #3
Excuse me for intruding, but I followed examples and ended up with a
similar architecture:

from Tkinter import *
class MyMain(Frame):
def __init__(self, master):
self.root = master
self.master=master
root = Tk()
app = MyMain(root)
app.master.title("Object Editor")
root.mainloop()

Erick, are you saying it should be modified to something like :

from Tkinter import *
class MyMain(Tk):
...
...
app = MyMain()
app.title("My App")
app.mainloop()

Thanks,
Bill

Eric Brunel wrote:
On Wed, 06 Jul 2005 11:44:55 +0100, Richard Lewis
<ri**********@fastmail.co.uk> wrote:
Hi there,

I've got a tree control in Tkinter (using the ESRF Tree module) but I
can't get it to layout how I want it.

I'd like to have it so that it streches north/south (anchored to the top
and bottom), is of a fixed width and is anchored to the left hand side.
Here's my code (its derived from one of the examples from the ESRF web
site):

class MainWindow(Frame):


[snip code]

First of all, it is not a good idea to make your so-called window
inherit from Frame: a Frame is not a window in tk, but a generic
container. Creating a Frame without a container window will
automatically initialize the tk toolkit, creating a default window which
will become the default parent for widgets where you don't specify one.
According to the well-known "explicit is better than implicit"
principle, if a MainWindow instance are actually the main window for
your application, you'd really better inherit from the Tkinter class for
the main window, which is Tk. Doing it this way has a lot of advantages
over what you do; for example, if you later have to create a menu bar
for your application, you will be able to do it in the MainWindow class.
If you inherit from Frame, you won't get any access to the actual
window, so you won't be able to create a menu in it.

This may seems to be unrelated to your problem, but it's not: by
creating a Frame, you introduce one more unneeded container. So, in some
code you don't show here, you have to insert the MainWindow instance
into its parent window via a call to its pack or grid method. Since the
code you show seems to be correct, I guess the problem is in this call
to pack or grid, which probably does not tell the Frame how to behave
when its parent window is resized, causing it to get the default
behaviour, which is "do nothing at all".

To be sure this actually is the problem, try to replace the line:
Frame.__init__(self, master)
in MainWindow.__init__ by:
Frame.__init__(self, master, bg='blue', bd=2)
This way, a blue border will appear around the frame, allowing you to
see how it grows.
Then run your application, and resize the window. You should see that
the frame does not grow when the window grows, explaining why your tree
deos not grow (in fact, it would grow if its container did; but its
container doesn't...)

So you should either make your MainWindow class inherit from Tk, which
eliminates the unneeded container and the problems it may cause, or make
sure the pack or grid on your MainWindow instance actually tells the
container to grow with its container. With pack, it's quite easy: just
do myWindow.pack(fill=BOTH, expand=1). With grid, it's a bit more
complicated, since you will have to configure the grid on the container.

But basically, my advice would be:
- Never make your windows inherit from Frame; make them inherit from Tk
for the main window or from Toplevel for all other ones
- When you have resize problems, always check the whole widget hierarchy
from the actual window down to the widget showing the problem. The cause
is very often not on the widget itself, but on one of its containers.

HTH

Jul 21 '05 #4

On Wed, 06 Jul 2005 16:32:42 GMT, "William Gill" <no*****@gcgroup.net>
said:
Excuse me for intruding, but I followed examples and ended up with a
similar architecture:

from Tkinter import *
class MyMain(Frame):
def __init__(self, master):
self.root = master
self.master=master
root = Tk()
app = MyMain(root)
app.master.title("Object Editor")
root.mainloop()

Erick, are you saying it should be modified to something like :

from Tkinter import *
class MyMain(Tk):
...
...
app = MyMain()
app.title("My App")
app.mainloop()

This is what I've got now, and it works. I don't think I've seen many
examples which inherited from Tk, but it certainly solved my problem.
And I see the logic in it: Tk is the main window of an application,
while Frame is, as Eric said, just a generic container.

Cheers,
Richard
Jul 21 '05 #5
On Wed, 06 Jul 2005 16:32:42 GMT, William Gill <no*****@gcgroup.net> wrote:
Excuse me for intruding, but I followed examples and ended up with a
similar architecture:

from Tkinter import *
class MyMain(Frame):
def __init__(self, master):
self.root = master
self.master=master
root = Tk()
app = MyMain(root)
app.master.title("Object Editor")
root.mainloop()

Erick, are you saying it should be modified to something like :

from Tkinter import *
class MyMain(Tk):
...
...
app = MyMain()
app.title("My App")
app.mainloop()


Well, basically, that's what I'm saying; but your example is a bit better than the OP's.

Basically, the problem is that an instance of MyMain will just be some kind of graphical component that can be inserted into basically anything. So nothing prevents me to do for example:

root = Tk()
Label(root, text='This is my application').pack(side=TOP)
frm = Frame(root)
frm.pack(side=TOP)
app = MyMain(frm)
# You don't show where you pack or grid your MayMain instance in its
# parent, so I'm doing it explicitely here...
app.pack()
root.mainloop()

So the container for MyMain is a Tk instance in your example, and a Frame instance in mine. And it works, because it's basically the use case for Frame sub-classes: they can be pack'ed or grid'ed or place'd into anything.

So MyMain cannot make any assumption on its container (self.master in your first example), since it can be any valid container. So there are many things that you just can't do in MyMain, because you don't have a window. For example, you can't set the window title, or define a menu bar, since all these are defined via methods only available on windows, i.e. Tk or Toplevel instances.

Basically, you did this right, since you call app.master.title(...) in the main script, where you know that app.master is a Tk instance. But what can be the reason to do it *outside* MyMain? Isn't it the window itself that knows what title it should have?

So in your second version, you can do:

from Tkinter import *
class MyMain(Tk):
Tk.__init__(self)
self.title("My App")
...
....
app = MyMain()
app.mainloop()

And this always works: since an instance of MyMain is an instance of Tk, you do have a window on which to call title. Note that this cannot be safely done in your first version, since self.master may not have a title method (see my example above).

So you should really stick to the following rules:
- If you write a class defining the main window for your application, make it inherit from Tkinter.Tk
- If you write a class defining a "secondary" window for your application, make it inherit from Tkinter.Toplevel
- If you write a class defining a graphical component that can be placed anywhere in a GUI, make it inherit from Tkinter.Frame
This is basically just a matter of good OO programming: you should choose the most accurate super-classes for the classes you define, or someday, you'll run into problems...

HTH
--
python -c "print ''.join([chr(154 - ord(c)) for c in 'U(17zX(%,5.zmz5(17;8(%,5.Z65\'*9--56l7+-'])"
Jul 21 '05 #6
Eric Brunel wrote:
So you should either make your MainWindow class inherit from Tk, which
eliminates the unneeded container and the problems it may cause, or make
sure the pack or grid on your MainWindow instance actually tells the
container to grow with its container. With pack, it's quite easy: just
do myWindow.pack(fill=BOTH, expand=1). With grid, it's a bit more
complicated, since you will have to configure the grid on the container.


To expand on this, the grid-method uses a few calls that aren't
immediately obvious. Specifically, the containing object must have row
and columnconfigure called on them:
r = Tk()
g = Text(r)
h = Entry(r)
g.grid(row=1,sticky=N+S+E+W)
h.grid(row=2,sticky=E+W)
r.columnconfigure(0,weight=1)
r.rowconfigure(1,weight=1)
r.mainloop()


This creats a window containing a text widget above an entry widget.
Both will resize horizontally to fill the entire window, and the text
widget will resize vertically.
Jul 21 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Josh | last post by:
Caution, newbie approaching... I'm trying to come up with a very simple Tkinter test application that consists of a window with a drop-down menu bar at the top and a grid of colored rectangles...
2
by: Maboroshi | last post by:
Why when I use the sticky command with the grid layout manager won't my Listbox expand it stays in the center maybe I am missing something but from every tutorial I see it says to do it this way ...
5
by: Paul Rubin | last post by:
I have a gui with a bunch of buttons, labels, the usual stuff. It uses the grid manager: gui = Frame() gui.grid() gui.Label(....).grid() # put some widgets into the gui ... # more widgets...
3
by: Matt Hammond | last post by:
Here's a strange one in Tkinter that has me stumped: (I'm running python 2.4 on Suse Linux 9.3 64bit) I'm trying to make a set of Entry widgets with Label widgets to the left of each one, using...
3
by: dwelch91 | last post by:
I'm trying unsuccessfully to do something in Tk that I though would be easy. After Googling this all day, I think I need some help. I am admittedly very novice with Tk (I started with it...
5
by: H J van Rooyen | last post by:
Hi, I am struggling to get the pack method to do what I intend. I am trying to display user input in a seperate window, along with a little description of the field, something like this: ...
4
by: Simon Forman | last post by:
Hi all, I realize this is more of a Tk question than a python one, but since I'm using python and don't know Tcl/Tk I figured I'd ask here first before bugging the Tcl folks. I am having a...
1
kaarthikeyapreyan
by: kaarthikeyapreyan | last post by:
Beginners Game- Tic-Tac-Toe My first attempt after learning Tkinter from Tkinter import * import tkFont class myApp: """ Defining The Geometry of the GUI And the variables Used In the...
2
by: skanemupp | last post by:
so my little calculator works perfectly now. just having some trouble with the layout. this whole tkinter-thing seems to be more tricky than it should be. how can i make the 4 column of buttons...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.