Is it possible to dynamically scale a tkinter window? - python

For my current Python project, I usually work at college on an x sized monitor, however when I want to work on it at home I have a much smaller screen. The majority of my widgets are currently sized with height and width parameters, and so when I work at home, my Tkinter frames that had been adjusted to fit my work monitor are then too big for the home screen, and only about two-thirds of my frame content then appears on the screen. I am using grid geometry.
There are also issues even when widgets don't have height parameters, for example, as there are simply too many rows of widgets to fit on my smaller screen.
Is it possible to scale Tkinter frames at all, so that when I come home to work on my project my window proportionately reduces in size to fit my smaller screen?
An example class is below:
class home_page(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="white")
h_title = tk.Label(self, text="Welcome to Fantasy Football!", fg="white", height=2, width=60, anchor="center", bg="#0ebf08", font=controller.title_font)
h_squad_hub_lb = tk.Label(self, text="Squad Hub", fg="white", width=13, anchor="center", bg="#38003c", font=controller.title_font)
squad_hub_text = "Selection headaches keeping you up\nat night? View your team below: "
h_sh_text = tk.Label(self, text=squad_hub_text, bg="white", font=("Segoe UI", 13))
h_view_team_bt = tk.Button(self, text="View Team", bg="#38003c", fg="white", command=lambda: controller.show_frame("pitch_view_team_page"))
h_transfers_bt = tk.Button(self, text="Transfers", bg="#38003c", fg="white", command=lambda: controller.show_frame("pitch_view_transfers_page"))
self.sh_img = PhotoImage(file = "Miscellaneous images/Squad Hub.png")
h_sh_img = tk.Label(self, image=self.sh_img)
h_rules_lb = tk.Label(self, text="Rules", fg="white", bg="#38003c", width=13, anchor="center", font=controller.title_font)
rules_text = "Need to know the game before you can\ncrush it? Check out our rules below: "
h_r_text = tk.Label(self, text=rules_text, bg="white", font=("Segoe UI", 13))
h_selection_info_bt = tk.Button(self, text="Selection Info", bg="#38003c", fg="white", command=lambda: controller.show_frame("seli_rules_page"))
h_scoring_info_bt = tk.Button(self, text="Scoring Info", bg="#38003c", fg="white", command=lambda: controller.show_frame("scoi_rules_page"))
self.r_img = PhotoImage(file = "Miscellaneous images/Rules.png")
h_r_img = tk.Label(self, image=self.r_img)
h_stats_lb = tk.Label(self, text="Statistics", fg="white", bg="#38003c", width=13, anchor="center", font=controller.title_font)
stats_text= "Want some hard facts to help decide on\nyour transfers? Check out the stats below: "
h_s_text = tk.Label(self, text=stats_text, bg="white", font=("Segoe UI", 13))
h_table_bt = tk.Button(self, text="League Table", bg="#38003c", fg="white", command=lambda: controller.show_frame("lgetbl_stats_page"))
h_plrsts_bt = tk.Button(self, text="Player Stats", bg="#38003c", fg="white", command=lambda: controller.show_frame("plrsts_stats_page"))
self.s_img = PhotoImage(file = "Miscellaneous images/Stats.png")
h_s_img = tk.Label(self, image=self.s_img)
h_news_lb = tk.Label(self, text="News", fg="white", width=13, anchor="center", bg="#38003c", font=controller.title_font)
news_text = "Want to hear what your favourite team is\nup to? Check out club news below: "
h_n_text = tk.Label(self, text=news_text, bg="white", font=("Segoe UI", 13))
h_club_list_bt = tk.Button(self, text="Club List", bg="#38003c", fg="white", command=lambda: controller.show_frame("clli_stats_page"))
h_preferences_bt = tk.Button(self, text="My Preferences", bg="#38003c", fg="white", command=lambda: controller.show_frame("mpref_settings_page"))
self.n_img = PhotoImage(file = "Miscellaneous images/News.png")
h_n_img = tk.Label(self, image=self.n_img)
h_title.grid(row=0, column=0, columnspan=15, pady=(60,60))
h_squad_hub_lb.grid(row=1, column=0, columnspan=3)
h_sh_text.grid(row=2, column=0, columnspan=3, rowspan=3)
h_sh_img.grid(row=2, column=3, rowspan=2)
h_view_team_bt.grid(row=4, column=0, pady=(20,40))
h_transfers_bt.grid(row=4, column=1, pady=(20,40))
h_rules_lb.grid(row=1, column=11, columnspan=3)
h_r_text.grid(row=2, column=11, columnspan=3, rowspan=2)
h_r_img.grid(row=2, column=14, rowspan=2)
h_selection_info_bt.grid(row=4, column=11, pady=(20,40))
h_scoring_info_bt.grid(row=4, column=12, pady=(20,40))
h_stats_lb.grid(row=5, column=0, columnspan=3)
h_s_text.grid(row=6, column=0, columnspan=3, rowspan=2)
h_s_img.grid(row=6, column=3, rowspan=2)
h_table_bt.grid(row=8, column=0, pady=(20,40))
h_plrsts_bt.grid(row=8, column=1, pady=(20,40))
h_news_lb.grid(row=5, column=11, columnspan=3)
h_n_text.grid(row=6, column=11, columnspan=3, rowspan=2)
h_n_img.grid(row=6, column=14, rowspan=2)
h_club_list_bt.grid(row=8, column=11, pady=(20,40))
h_preferences_bt.grid(row=8, column=12, pady=(20,40))

As a general rule of thumb, you should only give widths and heights to widgets where you really do care about widths and heights, such as with a text widget, listbox, or treeview. You usually shouldn't need to give a size to frames or the window as a whole.
When you do assign sizes, you should pick the minimum size necessary and then use pack, place, or grid options that allow the widgets to be resized when the window grows or shrinks.
Without more specifics about your particular problem it will be impossible for us to give more specific advice.

Related

Cannot resize the Tkinter buttons when using Sticky

I'm trying to adjust the buttons, but somehow even after changing the width, it won't change the size. This is my code:
if __name__ == '__main__':
# create application window
app = Tk()
# title
app.title("Music Players")
# geometry
app.geometry('500x300')
# background color
app.configure(bg='orange')
equation = StringVar()
window_1 = Label(app, textvariable=equation)
window_1.grid(columnspan=3, ipadx=100, ipady=10)
equation.set('music player')
window_2 = Entry(app, width=30)
window_2.grid(columnspan=5, ipadx=100, ipady=10)
# Create buttons and other accessories
button1 = Button(app, text='PLAY', fg='yellow', bg='purple',
command=lambda: press('PLAY'), height=2, width=1)
button1.grid(row=2, column=0, sticky="NSEW")
button2 = Button(app, text='STOP', fg='yellow', bg='purple',
command=lambda: press('STOP'), height=2, width=2)
button2.grid(row=2, column=1, sticky="NSEW")
button3 = Button(app, text='NEXT', fg='yellow', bg='purple',
command=lambda: press('NEXT'), height=2, width=2)
button3.grid(row=2, column=2, sticky="NSEW")
button4 = Button(app, text='PREVIOUS', fg='yellow', bg='purple',
command=lambda: press('PREVIOUS'), height=2, width=2)
button4.grid(row=2, column=3, sticky="NSEW")
I'm assuming it is because of sticky="NSEW", because when I remove it, the buttons change the size, but there is big spaces between the buttons and also, very spaced out, even though columns=0 and columns=1.
How can I change the size of buttons without getting rid of sticky? Or, without sticky, but having the buttons next to each other?
My expected output will be like this:
Thank you in advance!

How to Integrate my python code to my tkinter interface?

I have made a program where the user enter's a target number and 4 other numbers to make that target number. Right now I am having trouble to intergrate my tkinter interface to my code. So I am hoping that some one can help me
Tkinter interface:
window = Tk()
window.title("target number solution")
Label(window,image='', bg="white") .grid(row=0, column=0, sticky=W)
Label(window, text="Enter target number:",bg="black", fg="white", font="none 12 bold").grid(row=1, column=0, sticky=N)
textentry = Entry(window, width=20, bg="white")
textentry.grid(row=2, column=0, sticky=N)
Label(window, text="Enter first number:",bg="black", fg="white", font="none 12 bold").grid(row=4, column=0, sticky=N)
textentry = Entry(window, width=20, bg="white")
textentry.grid(row=5, column=0, sticky=N)
Label(window, text="Enter second number:",bg="black", fg="white", font="none 12 bold").grid(row=6, column=0, sticky=N)
textentry = Entry(window, width=20, bg="white")
textentry.grid(row=7, column=0, sticky=N)
Label(window, text="Enter third number:",bg="black", fg="white", font="none 12 bold").grid(row=8, column=0, sticky=N)
textentry = Entry(window, width=20, bg="white")
textentry.grid(row=9, column=0, sticky=N)
Label(window, text="Enter fourth number:",bg="black", fg="white", font="none 12 bold").grid(row=10, column=0, sticky=N)
textentry = Entry(window, width=20, bg="white")
textentry.grid(row=11, column=0, sticky=N)
Button(window, text="Solve", width=6, command=solver).grid(row=12, column=0, sticky=N)
output = Text(window, width=60, height=10, wrap=WORD, background="white")
output.grid(row=13, column=0, columnspan=1, sticky=N)
window.mainloop()
This is the code that needs to be linked with the tkinter interface:
from itertools import permutations,combinations_with_replacement
numbers = []
target = int(input())
operators = ["+","-","*","/"]
groups = ['X+X+X+X', 'X+X+(X+X)', 'X+(X+X)+X', '(X+X+X)+X', '(X+X)+X+X', 'X+(X+X+X)', '((X+X)+X)+X', 'X+(X+(X+X))', 'X+((X+X)+X)', '(X+X)+(X+X)', '(X+(X+X))+X']
seen = set()
for values in permutations(numbers,len(numbers)):
for operCombo in combinations_with_replacement(operators,len(numbers)-1):
for oper in permutations(operCombo,len(numbers)-1):
formulaKey = "".join(oper+values)
if formulaKey in seen: continue # ignore variations on parentheses alone
for pattern in groups:
formula = "".join(o+p for o,p in zip([""]+list(oper), pattern.split("+")))
formula = "".join(v+p for v,p in zip([""]+list(values),formula.split("X")))
try:
if eval(formula) == target:
global Answer
Answer = formula,"=",target
print(formula,"=",target)
seen.add(formulaKey)
break
except: pass
All suggestions will be grealty appriciated
You can store the values for each number in seperate IntVar variables, then get the values of these variables inside the solver function and perform all the operations that are in your second code. The code should be modularised with the use of a class containing functions that create the widgets and run the solver code. To read more about class-based declarations in Tkinter, read this.
from tkinter import Tk, Frame, Label, Button, IntVar, Entry, Text, W, N, WORD, INSERT
from itertools import permutations,combinations_with_replacement
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets()
def create_widgets(self):
self.target_num = IntVar()
self.num1 = IntVar()
self.num2 = IntVar()
self.num3 = IntVar()
self.num4 = IntVar()
# self.title("target number solution")
Label(self,image='', bg="white").grid(row=0, column=0, sticky=W)
Label(self, text="Enter target number:", bg="black", fg="white", font="none 12 bold").grid(row=1, column=0, sticky=N)
self.textentry1 = Entry(self, textvariable=self.target_num, width=20, bg="white")
self.textentry1.grid(row=2, column=0, sticky=N)
Label(self, text="Enter first number:",bg="black", fg="white", font="none 12 bold").grid(row=4, column=0, sticky=N)
self.textentry2 = Entry(self, textvariable=self.num1, width=20, bg="white")
self.textentry2.grid(row=5, column=0, sticky=N)
Label(self, text="Enter second number:",bg="black", fg="white", font="none 12 bold").grid(row=6, column=0, sticky=N)
self.textentry3 = Entry(self, textvariable=self.num2, width=20, bg="white")
self.textentry3.grid(row=7, column=0, sticky=N)
Label(self, text="Enter third number:",bg="black", fg="white", font="none 12 bold").grid(row=8, column=0, sticky=N)
self.textentry3 = Entry(self, textvariable=self.num3, width=20, bg="white")
self.textentry3.grid(row=9, column=0, sticky=N)
Label(self, text="Enter fourth number:",bg="black", fg="white", font="none 12 bold").grid(row=10, column=0, sticky=N)
self.textentry4 = Entry(self, textvariable=self.num4, width=20, bg="white")
self.textentry4.grid(row=11, column=0, sticky=N)
Button(self, text="Solve", width=6, command=self.solver).grid(row=12, column=0, sticky=N)
self.output = Text(self, width=60, height=10, wrap=WORD, background="white")
self.output.grid(row=13, column=0, columnspan=1, sticky=N)
def solver(self):
target = self.target_num.get()
number1 = self.num1.get()
number2 = self.num2.get()
number3 = self.num3.get()
number4 = self.num4.get()
numbers = [number1, number2, number3, number4]
operators = ["+","-","*","/"]
groups = ['X+X+X+X', 'X+X+(X+X)', 'X+(X+X)+X', '(X+X+X)+X', '(X+X)+X+X', 'X+(X+X+X)', '((X+X)+X)+X', 'X+(X+(X+X))', 'X+((X+X)+X)', '(X+X)+(X+X)', '(X+(X+X))+X']
seen = set()
for values in permutations(numbers,len(numbers)):
for operCombo in combinations_with_replacement(operators,len(numbers)-1):
for oper in permutations(operCombo,len(numbers)-1):
formulaKey = "".join(str(oper+values))
if formulaKey in seen: continue # ignore variations on parentheses alone
for pattern in groups:
formula = "".join(str(o)+str(p) for o,p in zip([""]+list(oper), pattern.split("+")))
formula = "".join(str(v)+str(p) for v,p in zip([""]+list(values),formula.split("X")))
try:
if eval(formula) == target:
Answer = formula,"=",target
print(formula,"=",target)
seen.add(formulaKey)
#insert value in output Textbox
self.output.insert(INSERT, Answer)
self.output.insert(END, '\n')
break
except: pass
root = Tk()
app = Application(master=root)
app.master.title("target number solution")
app.mainloop()
A few things that you can change/try:
Keep the "Entry" variables unique. Then extract each number using .get() command.
Use lambda in the command options of the Button as follows:
command = lambda: solver(num1, num2, num3, num4)
And if you want to display your returned number from 'solver', grid a Label in your tkinter window. Then use Label.config(text="Your number here") to show it in your tkinter window

Python Tkinter grid spacing of widgets and LablelFrames not right

I am designing a simple GUI in Python 2.7 Tkinter, but I can't get things to spread out as I want them. I have managed to get my various widgets roughly where I want them, however I can't seem to force spacing out and things are a little bunched up.
I have also tried to draw 3 LabelFrames to separate the window out, but widgets seem to fall over the LabelFrames. I am wondering how I can space this out a little better. The grid system seems to allow things to bunch up and ignores blank rows and columns as far as I can see.
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog, tkMessageBox
class FileZap():
def __init__(self, root):
root.title("TestGUI")
root.geometry("860x450")
self.topFrame = LabelFrame(root, text="Top Area")
self.topFrame.grid(row=1, column=1, rowspan=6, columnspan=7, padx=5, pady = 5, sticky="NSEW")
self.listbox1 = Listbox(root, width=50, selectmode="multiple")
self.listbox1.grid(row=3, column=2)
self.scrollbar = Scrollbar(orient=VERTICAL, command=self.listbox1.yview)
self.listbox1.config(yscrollcommand=self.scrollbar.set)
self.scrollbar.grid(row=3, column=3, sticky="ns")
self.listbox2 = Listbox(root, width=50)
self.listbox2.grid(row=3, column=4)
self.selectLabel = Label(root, text="Select a folder: ")
self.selectLabel.grid(row=3, column=1)
self.user1 = Entry(root, width="50")
self.user1.grid(row=2, column=2)
self.browse = Button(root, text="Browse")
self.browse.grid(row=2, column=3)
self.addItems = Button(root, text="Add to Selection")
self.addItems.grid(row=4, column=2)
self.clearItems = Button(root, text="Clear Selection")
self.clearItems.grid(row=4, column=4)
self.leftFrame = LabelFrame(root, text="Left Area")
self.leftFrame.grid(row=5, column=1, rowspan=6, columnspan=3, padx=5, pady = 5, sticky="NSEW")
self.replaceInLable = Label(root, text="String to replace: ")
self.replaceOutLable = Label(root, text="New string: ")
self.replaceInLable.grid(row=7, column=1)
self.replaceOutLable.grid(row=7, column=2)
self.replaceIn = Entry(root, width="20")
self.replaceOut = Entry(root, width="20")
self.replaceIn.grid(row=8, column=1)
self.replaceOut.grid(row=8, column=2)
self.replace = Button(root, text="Replace")
self.replace.grid(row=8,column=3)
self.rightFrame = LabelFrame(root, text="Right Area")
self.rightFrame.grid(row=5, column=4, rowspan=6, columnspan=3, padx=5, pady = 5, sticky="NSEW")
self.quit = Button(root, text="Exit", command=root.quit)
self.quit.grid(row=9, column=6)
root = Tkinter.Tk()
file_zap = FileZap(root)
root.mainloop()
I have tried various alterations but can't nail it! Any help would be much appreciated.
First, the columns / row adapt to there content so an empty one as a zero height/width. If you want to put space between your widgets use the padx and pady options in the .grid method. They can take either one number which will give the padding on both sides or a couple of numbers giving the padding on each side.
Secondly, if you want your widgets to be inside a LabelFrame, you need to create them with this LabelFrame as master instead of the main window.
from Tkinter import LabelFrame, Tk, Button, Label
root = Tk()
# make row 0 resize with the window
root.rowconfigure(0, weight=1)
# make column 0 and 1 resize with the window
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
# create LabelFrames
top_frame = LabelFrame(root, text="top")
left_frame = LabelFrame(root, text="left")
right_frame = LabelFrame(root, text="right")
top_frame.grid(row=0, column=0, columnspan=2, padx=10, pady=(10,4), sticky="nsew")
left_frame.grid(row=1, column=0, padx=(10,4), pady=4, sticky="nsew")
right_frame.grid(row=1, column=1, padx=(4,10), pady=4, sticky="nsew")
#create widgets inside top_frame
Label(top_frame, text="I'm inside top_frame").pack()
Button(top_frame, text="Top").pack()
#create widgets inside left_frame
Label(left_frame, text="I'm inside left_frame").pack()
Button(left_frame, text="Left").pack()
#create widgets inside top_frame
Label(right_frame, text="I'm inside right_frame").pack()
Button(right_frame, text="Right").pack()
Button(root, text="Quit", command=root.destroy).grid(row=2, column=0,
columnspan=2, pady=10)
root.mainloop()

tkinter ListBox and Label position

I am little bit comfused with grid system in tkinter Python. Can anyone show how to make it in right way?! ListBox and Label items positions are not in the places where I expexted to see them.
CODE:
self.third_label = Label(self, text="TEXT")
self.third_label.grid(row=2, column=0, columnspan=4, padx=10, pady=10, sticky=W)
self.fourth_label = Label(self, text="LONG TEXT")
self.fourth_label.grid(row=2, column=1, columnspan=4, padx=10, pady=10, sticky=W)
self.fifth_label = Label(self, text="SOME TEXT")
self.fifth_label.grid(row=2, column=2, columnspan=6, padx=10, pady=10, sticky=W)
self.sixth_label = Label(self, text="BIG TEXT")
self.sixth_label.grid(row=2, column=3, columnspan=4, padx=10, pady=10, sticky=W)
self.first_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.first_listbox.grid(row=3, column=0, columnspan=4, padx=10, pady=10, sticky=W)
self.second_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.second_listbox.grid(row=3, column=2, columnspan=4, padx=10, pady=10, sticky=W)
self.third_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.third_listbox.grid(row=3, column=4, columnspan=4, padx=10, pady=10, sticky=W)
self.fourth_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.fourth_listbox.grid(row=3, column=6, columnspan=4, padx=10, pady=10, sticky=W)
What I have right now:
Just Example:
The grid system works fine. The problem is your columnspans, which don't make much sense. You're gridding the widgets into certain column positions then giving them a columnspan that is beyond the range of where the next widget is to be gridded so on and so forth.
Small example:
import string
import tkinter as tk
root = tk.Tk()
for i in range(3):
tk.Label(root, text=string.ascii_letters).grid(row=0, column=i)
tk.Listbox(root, width=40).grid(row=1, column=i)
root.mainloop()
Edit from comments (for listbox size):
To get the number of lines in a listbox you can use the .size() method.
Image:

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()
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.
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()

Categories