473,659 Members | 2,690 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(Fram e):
def __init__(self, master):
Frame.__init__( self, master)
self.document = # new DOM document
self.create_sit e_list()

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

self.site_list = Tree.Tree(maste r=self,\
root_id="root", \
root_label="Sit e",\
get_contents_ca llback=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_rowco nfigure(0, weight=1)

vsb = Scrollbar(self, orient=VERTICAL )
vsb.grid(row=0, column=1, sticky=NS)
self.site_list. configure(yscro llcommand=vsb.s et)
vsb.configure(c ommand=self.sit e_list.yview)

hsb = Scrollbar(self, orient=HORIZONT AL)
hsb.grid(row=1, column=0, sticky=EW+S)
self.site_list. configure(xscro llcommand=hsb.s et)
hsb.configure(c ommand=self.sit e_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 8247
On Wed, 06 Jul 2005 11:44:55 +0100, Richard Lewis <ri**********@f astmail.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(Fram e):

[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.__in it__ 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(f ill=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.zmz 5(17;8(%,5.Z65\ '*9--56l7+-'])"
Jul 21 '05 #2

On Wed, 06 Jul 2005 17:36:01 +0200, "Eric Brunel"
<er*********@de spammed.com> said:
On Wed, 06 Jul 2005 11:44:55 +0100, Richard Lewis
<ri**********@f astmail.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(Fram e):

[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=mas ter
root = Tk()
app = MyMain(root)
app.master.titl e("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**********@f astmail.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(Fram e):


[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.__in it__ 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(f ill=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*****@gcgrou p.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=mas ter
root = Tk()
app = MyMain(root)
app.master.titl e("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*****@gcgrou p.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=mas ter
root = Tk()
app = MyMain(root)
app.master.titl e("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').p ack(side=TOP)
frm = Frame(root)
frm.pack(side=T OP)
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.titl e(...) 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__(sel f)
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.Topleve l
- 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.zmz 5(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(f ill=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,st icky=N+S+E+W)
h.grid(row=2,st icky=E+W)
r.columnconfigu re(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
5968
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 filling the remainder of the window. Mind you, this is a contrived test application to help me understand Tkinter and Python, not an actual application yet. I've trivially subclassed Tkinter.Canvas into ColorCanvas, added a bunch of ColorCanvases...
2
1712
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 I am running Python2.3.4 on winxp I haven't tried it on linux yet Any Ideas are appreciated Let me know if I am not being clear enough
5
1647
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 Now at the the very bottom of the gui, I want to add two more buttons, let's say "stop" and "go". I want "stop" to appear in the gui's lower
3
2145
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 the grid layout. If I make and grid the Label *before* the Entry then the Entry widget doesn't seem to work - it lets me put the cursor in it, but I can't type! See example code below. Is this just me doing something really really silly, or is...
3
3602
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 yesterday), so I am sure I am overlooking something simple. The basic idea is that my application will consist of a series of modal dialogs, that are chained together in "wizard" fashion. There will be some processing in between dialogs, but for the most...
5
3529
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: Current entry Company : entered co. name First entry : entered stuff The second entry: more entered stuff
4
4161
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 terrible time trying to get a pack() layout working. I have three frames stacked top to bottom and stretching across the master window from edge to edge.
1
5659
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 The methods
2
3520
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 have the same distance and size between them as the other 3 columns? and how can i make the top entry end where the 2nd row entry ends(meaning the top entry will be longer)? why are the 4th row split from the others? hard to fix the problems...
0
8427
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8332
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8525
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8627
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7356
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6179
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2750
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1975
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.