Tkinter buttons change size when font is added to a whole row - python

I'm making a tic-tac-toe game in python and right now I'm designing the GUI using Tkinter. The problem is that when I add 3 X's or O's to a row, the height of the button shrinks. I've played around with (i)padx and (i)pady and changing the font size, but nothing I've done has solved the issue. Anyone know how to fix this?
from tkinter import *
win = Tk()
win.configure(bg='light blue')
win.geometry('430x560')
win.title('TicTacToe')
win.resizable(False, False)
lblTitle = Label(win, text='Tic-Tac-Toe', font="Verdana 25 bold", fg='thistle4', bg='azure2',
highlightthickness=2, highlightbackground='thistle3')
lblTitle.pack(ipadx=20, ipady=5, padx=50, pady=10)
p1_turn = False
def click(ind):
if p1_turn:
btnTTT[ind].config(text="X", font='Verdana 45 bold')
else:
btnTTT[ind].config(text="O", font='Verdana 45 bold')
tttFrame = Frame(win, bg='azure2', highlightthickness=2, highlightbackground='thistle3')
tttFrame.pack()
btnTTT = list()
i = 0
for row in range(3):
for col in range(3):
btnTTT.append(Button(tttFrame, text="", bg='cadet blue', height=1, width=1,
fg='thistle', font="Verdana 50", relief='groove',
command=lambda c=i: click(c)))
btnTTT[i].grid(row=row, column=col, sticky="nesw", padx=15, pady=10, ipadx=15, ipady=15)
i = i + 1
mainFrame = Frame(win, bg='azure2', highlightthickness=2, highlightbackground='thistle3')
mainFrame.pack(pady=10)
scoreFrame = Frame(mainFrame, bg='azure2')
scoreFrame.grid(row=0, column=0, pady=10)
scoreboard = LabelFrame(scoreFrame, bg='azure2', fg='thistle4', text='Score', font='Verdana 15 bold', labelanchor='nw')
scoreboard.pack(padx=15)
lblPX = Label(scoreboard, bg='thistle', text="Player X:")
lblPX.grid(row=0, column=0, pady=5, padx=5)
lblPO = Label(scoreboard, bg='thistle', text="Player O:")
lblPO.grid(row=1, column=0, pady=5, padx=5)
lblPXScore = Label(scoreboard, bg='white', text=' ', relief='sunken')
lblPXScore.grid(row=0, column=1, padx=5)
lblPOScore = Label(scoreboard, bg='white', text=' ', relief='sunken')
lblPOScore.grid(row=1, column=1, padx=5)
butFrame = Frame(mainFrame, bg='azure2')
butFrame.grid(row=0, column=1)
btnReset = Button(butFrame, text="Reset", font='Verdana 15', fg='thistle')
btnReset.grid(row=0, column=0, padx=15, pady=5, ipady=4, ipadx=3)
btnExit = Button(butFrame, text='Exit', font='Verdana 15', fg='thistle')
btnExit.grid(row=1, column=0, padx=15, pady=5, ipady=3, ipadx=9)
win.mainloop()

It appears that you are having a format problem where the text change is directly changing the size of your button...
Verdana 45 bold
needs to match
Verdana 50"
Notice how one is size 50 and not bold, while the other is 45 and bold? If you change the top line to Verdana 50 and remove "bold" this will directly fix your issue.
For me the issues were on line 18, 19 that need to match line 32.

Related

How to get only a corresponding entry box regardless of how many times I change radiobutton?

from tkinter import *
win=Tk()
var = StringVar()
l = Label(win, bg='white', width=15)
l.grid(row=17,column=1,padx=10, pady=10, sticky='w')
def print1_selection():
if var.get()=="Number":
lab1= Label(win, text="Enter a number").grid(row=4, column=0)
ent1=Entry(win).grid(row=4, column=1)
l.config(text='you have selected ' + var.get())
elif var.get()=="Alphabet":
lab21= Label(win, text="Enter an alphabet").grid(row=5, column=0)
ent21=Entry(win).grid(row=5, column=1)
l.config(text='you have selected ' + var.get())
lbl4=Label(win, text="Select One", bg="crimson", fg="white", font=("times new
roman",15,"bold")).grid(row=1, column=0, padx=10, pady=10, sticky='w')
r1 = Radiobutton(win, text='Number',variable=var, value='Number', command=print1_selection, width=22)
r1.grid(row=2,column=0,padx=10, pady=10)
r2 = Radiobutton(win, text='Alphabet', variable=var, value='Alphabet', command=print1_selection, width=22)
r2.grid(row=2,column=1,padx=10, pady=10)
win.mainloop()
In this code I want that when I select radiobutton number, only enter a number should appear and same for the other.
But the problem is that when I select number after selecting alphabet, it shows both. I need only the selected one and eliminate the other instantly.
This is how I would approach this issue:
from tkinter import Tk, StringVar, Label, Frame, Entry, Radiobutton
def print1_selection():
for widget in entry_frame.winfo_children():
widget.destroy()
value = var.get()
lbl.config(text='You have selected ' + value)
if value == "Number":
Label(entry_frame, text="Enter a number").grid(row=0, column=0)
Entry(entry_frame).grid(row=0, column=1)
elif value == "Alphabet":
Label(entry_frame, text="Enter an alphabet").grid(row=0, column=0)
Entry(entry_frame).grid(row=0, column=1)
win = Tk()
var = StringVar(value=0)
entry_frame = Frame(win)
entry_frame.grid(row=2, column=0, columnspan=2)
lbl = Label(win, bg='white', width=20)
lbl.grid(row=3, column=0, columnspan=2, padx=10, pady=10, sticky='w')
Label(win, text="Select One", bg="crimson", fg="white", font=("times new roman", 15, "bold")).grid(row=0, column=0, padx=10, pady=10, sticky='w')
Radiobutton(win, text='Number', variable=var, value='Number', command=print1_selection, width=22).grid(row=1, column=0, padx=10, pady=10)
Radiobutton(win, text='Alphabet', variable=var, value='Alphabet', command=print1_selection, width=22).grid(row=1, column=1, padx=10, pady=10)
win.mainloop()
As You can see if You don't plan on using the widgets instance anywhere You don't have to assign it to a variable. Also no need to configure label in both statements since that will be done anyways so just do it at the beginning, also rows start from 0 too. Frames help with organizing widgets. Also if You want neither of the radiobuttons selected set the variable to 0.

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, clearing an Entry widget from a class

This is the class I'm calling and the function from a different file
class CalcFunc:
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
This is the Entry Box
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
This is the button I'm clicking to clear the Entry Box
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
I'm not sure what the syntax is to be able to to clear an Entry widget from a class basically. That code worked when I had it in the same file but my project requires it to be in a separate file. It's a class project for a calculator and the "clear" button clears the Entry widget. I can post my entire code if that helps. Thank you.
----EDIT----
My Class
import time
class CalcFunc:
def log(self, val):
myFile = open(r".\log.dat", "a")
myFile.write("%s\n" % val)
myFile.close()
def onScreen(self, iVal):
self.log(iVal)
currentTxt = self.getBtn.get()
updateEnt = self.getBtn.set(currentTxt + iVal)
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
def evaL(self):
self.log("=")
self.getBtn.set(str(eval(self.getBtn.get())))
self.log(self.getBtn.get())
def logLbl(self):
myFile = open(r".\log.dat", "a")
myFile.write("\n==================================\n")
myFile.write("Date: " + str(time.strftime("%m/%d/%Y")) + " -- Time: " + str(time.strftime("%I:%M:%S")))
myFile.write("\n==================================\n")
myFile.close()
My Program
from tkinter import *
import time
import clcClass
root = Tk()
root.title('skClc v1')
clc = clcClass.CalcFunc()
clc.logLbl()
clc.getBtn = StringVar()
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
button1 = Button(root, text="1", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('1'))
button2 = Button(root, text="2", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('2'))
button3 = Button(root, text="3", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('3'))
button4 = Button(root, text="4", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('4'))
button5 = Button(root, text="5", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('5'))
button6 = Button(root, text="6", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('6'))
button7 = Button(root, text="7", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('7'))
button8 = Button(root, text="8", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('8'))
button9 = Button(root, text="9", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('9'))
button0 = Button(root, text="0", height=1, width=5, bg='light blue', command=lambda:onScreen('0'))
buttonP = Button(root, text="+", height=1, width=5, bg='gray', command=lambda:clc.onScreen('+'))
buttonM = Button(root, text="-", height=1, width=5, bg='gray', command=lambda:clc.onScreen('-'))
buttonMM = Button(root, text="x", height=1, width=5, bg='gray', command=lambda:clc.onScreen('*'))
buttonDD = Button(root, text="รท", height=1, width=5, bg='gray', command=lambda:clc.onScreen('/'))
buttonEE = Button(root, text="=", height=1, width=5, bg='light green', command=clc.evaL)
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
button1.grid(row=1, column=0, pady=5)
button2.grid(row=1, column=1, pady=5)
button3.grid(row=1, column=2, pady=5)
button4.grid(row=2, column=0, pady=5)
button5.grid(row=2, column=1, pady=5)
button6.grid(row=2, column=2, pady=5)
button7.grid(row=3, column=0, pady=5)
button8.grid(row=3, column=1, pady=5)
button9.grid(row=3, column=2, pady=5)
button0.grid(row=4, column=0, pady=5)
buttonP.grid(row=4, column=1, pady=5)
buttonM.grid(row=4, column=2, pady=5)
buttonEE.grid(row=5, column=0, pady=5)
buttonDD.grid(row=5, column=1, pady=5)
buttonMM.grid(row=5, column=2, pady=5)
buttonCC.grid(row=6, column=0, pady=5, columnspan=3)
root.maxsize(140,245);
root.minsize(140,245);
root.mainloop()
ent = Entry(root, ....)
clc = clcClass.CalcFunc(ent)
class CalcFunc:
def __init__(self, entry):
self.entry = entry
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Here's an abbreviated example:
#my_entry.py
from tkinter import END
import time
class EntryWithLogger:
def __init__(self, entry):
self.entry = entry
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if an exception occurs, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.entry.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Note that I didn't use a StringVar(), which doesn't appear to be necessary. If you need it, you can always pass it as an argument to __init__(), then store it on self.
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = tk.Entry(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
entry_with_logger = me.EntryWithLogger(entry)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='light blue',
command=lambda x=button_text: entry_with_logger.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry_with_logger.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()
Or, you could do it like this:
#my_entry.py
from tkinter import Entry, END
import time
class EntryWithLogger(Entry):
#Because __init__() is not implemented, the parent class's __init__() gets
#called, so you create an EntryWithLogger just like you would an Entry.
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if there is an exception, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.delete(0, END)
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = me.EntryWithLogger(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='LightBlue',
command=lambda x=button_text: entry.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()

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