Andrea
Andrea

Reputation: 355

Tkinter: right align Labels within stretched LabelFrames using grid

Using grid in tkinter, I'm trying to align a set of frames (I would love to post a picture, but I'm not allowed.)

I've two outer LabelFrames of different sizes and on top of each other which I'd like to stretch and align. Within the bottom frame, I've a stack of several other LabelFrames and within each of the LabelFrames there is a Label. I would like for the LabelFrames to extend as much as the outer container and for each of the inner Labels to be right align with respect to the containing LabelFrame.

I've tried, without success, with various combinations of sticky, anchor, justify.

Any suggestion, recommendation?

#!/usr/bin/env python
import Tkinter as tk



class AlignTest(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.parent = parent
        self.grid()
        self.parent.title('Align test')
        self.createMenus()
        self.createWidgets()


    def createMenus(self):
        # Menu
        self.menubar = tk.Menu(self.parent)
        self.parent.config(menu=self.menubar)

        # Menu->File
        self.fileMenu = tk.Menu(self.menubar)

        # Menu->Quit
        self.fileMenu.add_command(label='Quit',
                                  command=self.onExit)

        # Create File Menu
        self.menubar.add_cascade(label='File',
                                 menu=self.fileMenu)


    def createWidgets(self):

        # Main frame
        self.mainFrame = tk.Frame(self.parent)
        self.mainFrame.grid(row=0, column=0)

        # Outer LabelFrame1
        self.outerLabelFrame1 = tk.LabelFrame(self.mainFrame,
                                             text='Outer1')
        self.outerLabelFrame1.grid(row=0, column=0)

        # Inner Label
        self.innerLabel = tk.Label(self.outerLabelFrame1,
                                   text='This is a longer string, for example!')
        self.innerLabel.grid(row=0, column=0)


        # Outer LabelFrame2
        self.outerLabelFrame2 = tk.LabelFrame(self.mainFrame,
                                             text='Outer2')
        self.outerLabelFrame2.grid(row=1, column=0, sticky='ew')

        # Inner labelFrames each with a single labels
        self.innerLabel1 = tk.LabelFrame(self.outerLabelFrame2,
                                         bg='yellow',
                                         text='Inner1')
        self.innerLabel1.grid(row=0, column=0, sticky='ew')
        self.value1 = tk.Label(self.innerLabel1,
                               bg='green',
                               text='12.8543')
        self.value1.grid(row=0, column=0, sticky='')

        self.innerLabel2 = tk.LabelFrame(self.outerLabelFrame2,
                                         bg='yellow',
                                         text='Inner2')
        self.innerLabel2.grid(row=1, column=0, sticky='ew')
        self.value2 = tk.Label(self.innerLabel2,
                               bg='green',
                               text='0.3452')
        self.value2.grid(row=0, column=0, sticky='')

        self.innerLabel3 = tk.LabelFrame(self.outerLabelFrame2,
                                         bg='yellow',
                                         text='Inner3')
        self.innerLabel3.grid(row=2, column=0, sticky='')
        self.value3 = tk.Label(self.innerLabel3,
                               bg='green',
                               text='123.4302')
        self.value3.grid(row=0, column=0, sticky='')

    def onExit(self):
        self.parent.quit()



def main():
    root = tk.Tk()
    app = AlignTest(root)
    app.mainloop()



if __name__ == '__main__':
   main()

Upvotes: 1

Views: 2608

Answers (2)

Andrea
Andrea

Reputation: 355

Thanks to Bryan's comment on weight, here is a working version of the code as potential reference. (I'll add pictures when allowed.)

#!/usr/bin/env python
import Tkinter as tk



class AlignTest(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.parent = parent
        self.grid()
        self.parent.title('Align test')
        self.createMenus()
        self.createWidgets()


    def createMenus(self):
        # Menu
        self.menubar = tk.Menu(self.parent)
        self.parent.config(menu=self.menubar)

        # Menu->File
        self.fileMenu = tk.Menu(self.menubar)

        # Menu->Quit
        self.fileMenu.add_command(label='Quit',
                                  command=self.onExit)

        # Create File Menu
        self.menubar.add_cascade(label='File',
                                 menu=self.fileMenu)


    def createWidgets(self):

        # Main frame
        self.mainFrame = tk.Frame(self.parent)
        self.mainFrame.grid(row=0, column=0)

        # Outer LabelFrame1
        self.outerLabelFrame1 = tk.LabelFrame(self.mainFrame,
                                             text='Outer1')
        self.outerLabelFrame1.grid(row=0, column=0)

        # Inner Label
        self.innerLabel = tk.Label(self.outerLabelFrame1,
                                   text='This is a longer string, for example!')
        self.innerLabel.grid(row=0, column=0)


        # Outer LabelFrame2
        self.outerLabelFrame2 = tk.LabelFrame(self.mainFrame,
                                             text='Outer2')
        self.outerLabelFrame2.grid(row=1, column=0, sticky='ew')
        self.outerLabelFrame2.grid_columnconfigure(0, weight=1)

        # Inner labelFrames each with a single labels
        self.innerLabel1 = tk.LabelFrame(self.outerLabelFrame2,
                                         bg='yellow',
                                         text='Inner1')
        self.innerLabel1.grid(row=0, column=0, sticky='ew')
        self.innerLabel1.grid_columnconfigure(0, weight=1)
        self.value1 = tk.Label(self.innerLabel1,
                               bg='green',
                               anchor='e',
                               text='12.8543')
        self.value1.grid(row=0, column=0, sticky='ew')


        self.innerLabel2 = tk.LabelFrame(self.outerLabelFrame2,
                                         bg='yellow',
                                         text='Inner2')
        self.innerLabel2.grid(row=1, column=0, sticky='ew')
        self.innerLabel2.grid_columnconfigure(0, weight=1)
        self.value2 = tk.Label(self.innerLabel2,
                               bg='green',
                               anchor='e',
                               text='0.3452')
        self.value2.grid(row=0, column=0, sticky='ew')


        self.innerLabel3 = tk.LabelFrame(self.outerLabelFrame2,
                                         bg='yellow',
                                         text='Inner3')
        self.innerLabel3.grid(row=2, column=0, sticky='ew')
        self.innerLabel3.grid_columnconfigure(0, weight=1)
        self.value3 = tk.Label(self.innerLabel3,
                               bg='green',
                               anchor='e',
                               text='123.4302')
        self.value3.grid(row=0, column=0, sticky='ew')

    def onExit(self):
        self.parent.quit()



def main():
    root = tk.Tk()
    app = AlignTest(root)
    app.mainloop()



if __name__ == '__main__':
   main()

Upvotes: 0

Bryan Oakley
Bryan Oakley

Reputation: 385910

Without even running your code I see two problems. The first is that you aren't always using the sticky parameter when calling grid. That could be part of the problem. I've rarely ever used grid without using that parameter.

The second problem is that you aren't giving any of your rows and columns any weight. Without a positive weight, columns and rows will only ever use up exactly as much space as they need for their contents, and no more. Any extra space goes unallocated.

A good rule of thumb is that in every widget that is being used as a container for other widgets (typically, frames), you should always give at least one row and one column a positive weight.

As a final suggestion: during development it's really helpful to give each of your frames a distinctive color. This really helps to visualize how the frames are using the available space.

Upvotes: 1

Related Questions