user4777887
user4777887

Reputation: 1

Python 2.7 Tkinter Grid Layout Manager not working as imagined

Dear StackOverflow community,

I am trying to get my head around programming with Python and I am having a hard time with the grid layout manager. I have been trying to find the answer myself and tried various options, but I just can't get my UI to look how I want it to.

I hope that you can help me. Unfortunately, I cannot post pictures because I am new here. But basically I wanted all the coloured buttons on the left hand side EVENLY spaced on top each other, in column 1. Then the Labels in column 2 and the text areas in column 3.

I also wanted to create a border at the bottom with the close button underneath, but this doesn't even show up at all.

Please could you give me some hints as to what I am doing wrong?

import Tkinter
from Tkinter import *
from ttk import Frame, Button, Style


class KarateSyllabus(Frame):
    """A program that displays karate grading syllabi"""


  #define the constructor
    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent

        self.initUI()


    #define the GUI
    def initUI(self):

        #define the basic parameters of the window
        self.parent.title("Karate Syllabus")
        self.style = Style()
        self.style.theme_use("default")
        #self.parent.geometry("500x500")
        self.parent.config(background = "black")
        self.parent.wm_iconbitmap("favicon.ico")
        self.grid()


        #create the buttons for the syllabus
        button1 = Tkinter.Button(self, text = "White Belt", bg = "white",         height=1, width =10).grid(row=0, column=0, pady=4, padx=10, sticky=N)
        button2 = Tkinter.Button(self, text = "Red Belt",   bg="red", height=1, width =10).grid(row=1,column=0, pady=4, padx=10,  sticky=N )
        button3 = Tkinter.Button(self, text = "Orange Belt",bg="orange", height=1, width =10).grid(row=2,column=0, pady=4, padx=10,  sticky=N)
        button4 = Tkinter.Button(self, text = "Yellow Belt",bg="yellow", height=1, width =10).grid(row=3, column=0, pady=4, padx=10,  sticky=N)
        button5 = Tkinter.Button(self, text = "Green Belt", bg="green", height=1, width =10).grid(row=4, column=0, pady=4, padx=10,  sticky=N)
        button6 = Tkinter.Button(self, text = "Purple Belt",bg="purple", height=1, width =10).grid(row=5, column=0, pady=4, padx=10,  sticky=N)
        button7 = Tkinter.Button(self, text = "Brown Belt", bg="brown", height=1, width =10).grid(row=6, column=0, pady=4, padx=10,  sticky=N)
        button8 = Tkinter.Button(self, text = "Black Belt", bg="black", foreground="white", height=1, width =10).grid(row=7, column=0, pady=2, padx=10,  sticky=N)


        #create the three text areas to display the text and according labels
        BasicsLabel = Label(self, text="Basics:").grid(row =0, column =2)
        BasicTextArea = Text(self, width=50, height=6, takefocus=0)
        BasicTextArea.grid(row=0, column=3, padx=10, pady=2)
        BasicTextArea.config(font =("Arial",10), bg="grey", wrap = WORD)

        KataLabel = Label(self, text="Kata:").grid(row =2, column =2)
        KataTextArea = Text(self, width=50, height=6, takefocus=0)
        KataTextArea.grid(row=2, column=3, padx=30, pady=2)
        KataTextArea.config(font =("Arial",10), bg="grey")

        KumiteLabel = Label(self, text="Kumite:").grid(row =3, column =2)
        KumiteTextArea = Text(self, width=50, height=6, takefocus=0)
        KumiteTextArea.grid(row=3, column=3, padx=10, pady=2)
        KumiteTextArea.config(font =("Arial",10), bg="grey")

        #create the second frame for the bottom with the close button
        frame = Frame(self, relief=RAISED, borderwidth=1)
        frame.grid(row=8, column= 1)

        closeButton = Button(self, text="Exit")
        closeButton.grid(row = 8, column = 3)



def main():

    root = Tk()
    app = KarateSyllabus(root)
    root.mainloop()


if __name__ == '__main__':
    main()  

Upvotes: 0

Views: 1247

Answers (2)

davidedb
davidedb

Reputation: 876

You should use at least a Frame to group all the left buttons and another one for the Exit button, as in the following code:

import Tkinter
from ttk import Frame, Button, Style

class KarateSyllabus(Frame):
    """A program that displays karate grading syllabi"""

  #define the constructor
    def __init__(self, parent):
        Frame.__init__(self, parent)   
        self.parent = parent
        self.initUI()

    #define the GUI
    def initUI(self):
        #define the basic parameters of the window
        self.parent.title("Karate Syllabus")
        self.style = Style()
        self.style.theme_use("default")
        #self.parent.geometry("500x500")
        self.parent.config(background = "black")
        self.parent.wm_iconbitmap("favicon.ico")
        self.grid(sticky=Tkinter.NSEW)

        button_panel = Frame(self)

        #create the buttons for the syllabus
        button1 = Tkinter.Button(button_panel, text="White Belt",  bg="white",  height=1, width =10).grid(row=0, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button2 = Tkinter.Button(button_panel, text="Red Belt",    bg="red",    height=1, width =10).grid(row=1, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button3 = Tkinter.Button(button_panel, text="Orange Belt", bg="orange", height=1, width =10).grid(row=2, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button4 = Tkinter.Button(button_panel, text="Yellow Belt", bg="yellow", height=1, width =10).grid(row=3, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button5 = Tkinter.Button(button_panel, text="Green Belt",  bg="green",  height=1, width =10).grid(row=4, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button6 = Tkinter.Button(button_panel, text="Purple Belt", bg="purple", height=1, width =10).grid(row=5, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button7 = Tkinter.Button(button_panel, text="Brown Belt",  bg="brown",  height=1, width =10).grid(row=6, column=0, pady=4, padx=10, sticky=Tkinter.N)
        button8 = Tkinter.Button(button_panel, text="Black Belt",  bg="black",  height=1, width =10, foreground="white").grid(row=7, column=0, pady=2, padx=10, sticky=Tkinter.N)

        button_panel.grid(row=0, column=0, rowspan=3, sticky=Tkinter.N)

        #create the three text areas to display the text and according labels
        BasicsLabel = Tkinter.Label(self, text="Basics:").grid(row=0, column=1, sticky=Tkinter.N)
        BasicTextArea = Tkinter.Text(self, width=50, height=6, takefocus=0)
        BasicTextArea.grid(row=0, column=2, padx=10, pady=2, sticky=Tkinter.NSEW)
        BasicTextArea.config(font=("Arial",10), bg="grey", wrap=Tkinter.WORD)

        KataLabel = Tkinter.Label(self, text="Kata:").grid(row=1, column=1, sticky=Tkinter.N)
        KataTextArea = Tkinter.Text(self, width=50, height=6, takefocus=0)
        KataTextArea.grid(row=1, column=2, padx=10, pady=2, sticky=Tkinter.NSEW)
        KataTextArea.config(font =("Arial",10), bg="grey")

        KumiteLabel = Tkinter.Label(self, text="Kumite:").grid(row=2, column=1, sticky=Tkinter.N)
        KumiteTextArea = Tkinter.Text(self, width=50, height=6, takefocus=0)
        KumiteTextArea.grid(row=2, column=2, padx=10, pady=2, sticky=Tkinter.NSEW)
        KumiteTextArea.config(font=("Arial",10), bg="grey")

        #create the second frame for the bottom with the close button
        close_frame = Tkinter.Frame(self, relief=Tkinter.RAISED, borderwidth=2)
        close_frame.grid(row=3, column=0, columnspan=3, sticky=Tkinter.EW)
        close_frame.columnconfigure(0, weight=1)

        closeButton = Tkinter.Button(close_frame, text="Exit", command=self.quit)
        # Move 'Exit' to the right. Comment out next line to leave it centered.
        closeButton.grid(sticky=Tkinter.E)

        self.rowconfigure(0, weight=1)
        self.rowconfigure(1, weight=1)
        self.rowconfigure(2, weight=1)
        # Leave row 3 (close_frame) non-expandable.

        # Leave columns 1 and 2 (button_panel and labels) non-expandable.
        self.columnconfigure(2, weight=1)

        self.parent.rowconfigure(0, weight=1)
        self.parent.columnconfigure(0, weight=1)


def main():
    root = Tkinter.Tk()
    app = KarateSyllabus(root)
    root.mainloop()


if __name__ == '__main__':
    main()

Upvotes: 0

Bryan Oakley
Bryan Oakley

Reputation: 386342

It sounds like you don't need to be using grid, since you aren't creating a grid. It sounds like you want each column to be evenly spaced vertically, which precludes a grid-like layout.

You're creating three columns, so I would start with packing a frame along the bottom for your quit button, and then three vertical frames, packed left-to-right, all in the main window.

Next, pack the color buttons in the left-most frame, top to bottom. With the right options they will be evenly spaced (though you could also use grid if you want).

Finally, use the exact same technique for the other two columns - pack everything top-to-bottom, having each one expand to fill the area they are allotted.

Upvotes: 1

Related Questions