I am designing a front end using Tkinter but the .grid() option doesn't work as expected. I want to divide my screen to two section, LEFT and Right. All the buttons and labels on the left and the rest on the right.
# Initialise frames
self.frame_left = tk.Frame(root, bg = "pink", width = 100, height = 100).grid(row = 0, column = 0, sticky = 'E')
self.frame_right = tk.Frame(root, bg = "red", width = 100, height = 100).grid(row = 0, column = 1, sticky = 'W')
root.grid_columnconfigure(0, weight=0)
root.grid_columnconfigure(1, weight=0)
#labels
self.Name_Label = tk.Label(self.frame_left, text = "Name", font = 12, fg = 'green').grid(row = 1, column = 1)
self.Phone_Label = tk.Label(self.frame_left, text = "Phone Number", font = 12, fg= 'green').grid(row = 1, column =2)
self.University_label = tk.Label(self.frame_left, text = "University", font = 12, fg = 'green').grid(row = 1, column = 3)
#Search boxex
self.Name_box = tk.Entry(self.frame_left, width = 12, borderwidth = 2).grid(row = 2, column = 1)
self.Phone_box = tk.Entry(self.frame_left, width = 12, borderwidth = 2).grid(row = 2, column = 2)
self.Phone_box = tk.Entry(self.frame_left, width = 12, borderwidth = 2).grid(row = 2, column = 3)
# Buttons
self.Search_button = tk.Button(self.frame_left, text='Search', padx = 10, pady = 10, font = 12, fg = 'black').grid(row = 5, column = 1)
#Screen
#self.Screen = tk.Listbox(self.frame_right, width = 20, height = 20, font = 1).grid(row = 0, column = 0)
It seems the labels and buttons are being placed on the root window not the frames that has been defined.
Appreciate your help.
Regards
Khisrow
To divide your screen into 2 parts, you need to use the option columnconfigure:
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
This creates a grid on the root window with 2 columns in which your self.frame_left and self.frame_right can be placed.
When you store a .grid() item you are not storing the widget:
self.frame_left = tk.Frame(root, bg = "pink", width = 100, height = 100).grid(row = 0, column = 0, sticky = 'E')
Stores the grid object to the variable, not the Frame.
This can be fixed by doing the creation and grid in two lines.
import tkinter as tk
class Test():
def __init__(self):
root = tk.Tk()
#EXAMPLE OF DIFFERENCE
self.frame_left = tk.Frame(root, bg = "pink", width = 100, height = 100).grid(row = 0, column = 0, sticky = 'E')
print(self.frame_left, "DIDN'T STORE THE FRAME")
self.frame_left = tk.Frame(root, bg = "pink", width = 100, height = 100)
self.frame_left.grid(row = 0, column = 0, sticky = 'E')
print(self.frame_left, "STORED THE FRAME")
#EXAMPLE OF DIFFERENCE
# Initialise frames
self.frame_left = tk.Frame(root, bg = "pink", width = 100, height = 100)
self.frame_left.grid(row = 0, column = 0, sticky = 'E')
self.frame_right = tk.Frame(root, bg = "red", width = 100, height = 100)
self.frame_right.grid(row = 0, column = 1, sticky = 'W')
root.grid_columnconfigure(0, weight=0)
root.grid_columnconfigure(1, weight=0)
#labels
self.Name_Label = tk.Label(self.frame_left, text = "Name", font = 12, fg = 'green').grid(row = 1, column = 1)
self.Phone_Label = tk.Label(self.frame_left, text = "Phone Number", font = 12, fg= 'green').grid(row = 1, column =2)
self.University_label = tk.Label(self.frame_left, text = "University", font = 12, fg = 'green').grid(row = 1, column = 3)
#Search boxex
self.Name_box = tk.Entry(self.frame_left, width = 12, borderwidth = 2)
self.Name_box.grid(row = 2, column = 1)
self.Phone_box = tk.Entry(self.frame_left, width = 12, borderwidth = 2)
self.Phone_box.grid(row = 2, column = 2)
self.Phone_box = tk.Entry(self.frame_left, width = 12, borderwidth = 2)
self.Phone_box.grid(row = 2, column = 3)
# Buttons
self.Search_button = tk.Button(self.frame_left, text='Search', padx = 10, pady = 10, font = 12, fg = 'black').grid(row = 5, column = 1)
#Screen
#self.Screen = tk.Listbox(self.frame_right, width = 20, height = 20, font = 1).grid(row = 0, column = 0)
Test()
EDIT: added a listbox with scrollbar
# Screen
scrollbar = tk.Scrollbar(self.frame_right)
scrollbar.grid(row = 0, column = 1, sticky = 'nsw')
self.Screen = tk.Listbox(self.frame_right, width = 20, height = 5, font = 1)
self.Screen.grid(row = 0, column = 0, sticky = 'e')
self.Screen.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=self.Screen.yview)
Related
making an F1 application where users can type in a driver from the current grid [supported via autofill/suggestions], and then API fetches relevant stats
The issue I'm having is that I want the listbox to appear over another frame (called left_frame). However, what this does is that the listbox goes under left_frame , and not over it. Any thoughts of how to make it appear over the frame?
some approaches that I tried:
used .lift(), but .lift() only seems to work when it's relative to objects in the same frame
since I currently use .grid and placed the listbox in the root frame, I initially tried to put it in top_frame, but it then expands the top_frame. Since I have positioned all frames using .place(), I don't think I can use propagate(False) (I tried it , didn't work)
Here's a picture of the issues
Here's my code so far:
#import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
#set up main window components
root = Tk()
root.title("F1 Desktop Application")
root.geometry("500x600")
root.configure(bg="white")
#since same directory, can just use filename
root.iconbitmap("formula1_logo.ico")
#images
#creating canvas for image to go into
#canvas_f1_logo = Canvas(top_frame, width = 5, height = 5)
#canvas.grid(row = 0, column = 1)
#acquire image
#formula1_logo = ImageTk.PhotoImage(Image.open("formula1_logo.png"))
#resize image
#resized_formula1_logo = formula1_logo.resize((3,3), Image.ANTIALIAS)
#new_formula1_logo = ImageTK.PhotoImage(resized_formula1_logo)
#canvas.create_image(5,5, anchor = NW, image = new_formula1_logo)
#functions
#generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
#initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
#set up frames [main frames, can put frames within frames if needed]
#frame for search bar + magnifying glass
top_frame = LabelFrame(root, padx = 80, pady = 15)
top_frame.place(relx = 0.5, rely = 0.2, anchor = CENTER)
header_label = Label(top_frame, text = "F1 2022 Drivers App", pady = 20, font = ("Arial bold",14))
header_label.grid(row = 0, column = 0, pady = 2 )
search_button = Button(top_frame, text = "search", padx = 2, pady = 2)
search_button.grid(row = 1, column = 1)
# Update the Entry widget with the selected item in list
def check(e):
v= entry.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry.delete(0,END)
entry.insert(0,menu.get(menu.curselection()))
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
# Create an Entry widget
entry= Entry(top_frame)
entry.grid(row = 1, column = 0)
entry.bind('<KeyRelease>',check)
# Create a Listbox widget to display the list of items
menu= Listbox(root)
menu.grid(row = 2, column = 0, padx = 165, pady = 165)
menu.bind("<<ListboxSelect>>",fillout)
menu.lift()
# Add values to our combobox
hide_button(menu)
left_frame = LabelFrame(root, padx = 30, pady = 30)
left_frame.place(relx = 0.24, rely = 0.5, anchor = CENTER)
bottom_left_frame = LabelFrame(root, padx = 30, pady = 30)
bottom_left_frame.place(relx = 0.24, rely = 0.82, anchor = CENTER)
bottom_right_frame = LabelFrame(root, padx = 30, pady = 30)
bottom_right_frame.place(relx = 0.6, rely = 0.82)
basic_info = Label(left_frame, text = "Basic Info ", font = ("Arial bold",14))
basic_info.grid(row = 0, column = 0, pady = 3)
full_name = Label(left_frame, text = "Full Name : ")
full_name.grid(row = 1, column = 0, pady = 2)
driver_code = Label(left_frame, text = "Driver Code : ")
driver_code.grid(row = 2, column = 0, pady = 2)
nationality = Label(left_frame, text = "Nationality : ")
nationality.grid(row = 3, column = 0, pady = 2)
F1_career = Label(bottom_left_frame, text = "F1 Career ", font = ("Arial bold",14))
F1_career.grid(row = 0, column = 0, pady = 3)
wins = Label(bottom_left_frame, text = "Wins :")
wins.grid(row = 1, column = 0, pady = 2)
poles = Label(bottom_left_frame, text = "Poles :")
poles.grid(row = 2, column = 0, pady = 2)
drivers_championships = Label(bottom_left_frame, text = "Championships :")
drivers_championships.grid(row = 3, column = 0 , pady = 2)
F1_22_stats = Label(bottom_right_frame, text = "F1 22 Stats", font = ("Arial bold",14))
F1_22_stats.grid(row = 0, column = 0, pady = 3)
root.mainloop()
would appreciate the help!
What is the possible problem because every time I select a date there is an error which is "Column count doesn't match value count and row 1". The columns are correct and I also converted the date entry to string. But there it comes out. I would like to store it in the MySQL database. Hope someone can help thank you in advance.
Here's my full code:
from tkinter import *
from tkinter.ttk import Combobox
from tkcalendar import DateEntry
from tkinter import ttk
from tkinter import messagebox
import mysql.connector
def addData():
try:
full_name = full_name_entry.get()
if full_name == "":
messagebox.showerror(title = "Save Record Error", message = "You must fill field first")
else:
connection = mysql.connector.connect(
host = 'localhost',
username = 'root',
password = '',
database = 'scratch_database'
)
my_cursor = connection.cursor()
my_cursor.execute("insert into scratch_table values(%s,%s,%s,%s,%s)",
(fullName.get(),
srProject.get(),
contractStart.get(),
contractEnd.get(),
stat.get()
))
connection.commit()
connection.close()
messagebox.showinfo(title = "Information", message = "Record Saved!")
except Exception as e:
messagebox.showerror(title = "Scratch Data", message = e)
def databaseConnection():
try:
connection = mysql.connector.connect(
host = 'localhost',
username = 'root',
password = '',
database = 'scratch_database'
)
my_cursor = connection.cursor()
messagebox.showinfo(title = "Information", message = "You are connected to database")
connection.commit()
connection.close()
except Exception as e:
messagebox.showerror(title = "Connection Error", message = e)
def mainWindow():
window = Tk()
window.config(bg = 'white')
window.title("Sample Table for SR Data")
window.resizable(0,0)
window.geometry('1212x771')
global fullName
global srProject
global contractStart
global contractEnd
global stat
fullName = StringVar()
srProject = StringVar()
contractStart = StringVar()
contractEnd = StringVar()
stat = StringVar()
# FULLNAME LABEL
full_name = Label(window, text = "Full Name", font = ('Arial', 12), bg = 'white')
full_name.place(x = 30, y = 63)
global full_name_entry
# FULLNAME ENTRY
full_name_entry = Entry(window, font = ('Arial', 12), width = 30, highlightbackground = 'gray', highlightcolor = 'black',
highlightthickness = 1, bd = 0, textvariable = fullName)
full_name_entry.place(x = 34, y = 101)
# PROJECTS LABEL
projects = Label(window, text = "Positions", font = ('Arial', 12), bg = 'white')
projects.place(x = 30, y = 156)
# POSITIONS OPTIONS
projects_options = ['Agricultural Situation Report', 'ASPBI', 'BLPS', 'BPCS', 'CPH', 'Census Evaluation Survey',
'Cities and Municipalities Competitive Index','CLPS', 'CSS', 'CBMS', 'Consumer Expectation Survey',
'Other Crop Survey', 'PCPS', 'PCSS', 'PPS', 'QaFS/QiFS', 'QSPBI', 'WSP/RPS', 'SICT', 'SOF', 'UGBSEA',
'ULE', 'CPS', 'CDSPDP', 'CLPS', 'SCMDV for 2021 PPCM', 'CDC', 'Quarterly Crops Production Survey',
'2021 CLPS','MPCSRS/PCSS/CSS 2021', 'January 2022 FPS'
]
# POSITIONS COMBOBOX
projects_combo_box = Combobox(window, values = projects_options, width = 28, font = ('Arial', 12), cursor = 'hand2', textvariable = srProject)
projects_combo_box.place(x = 34, y = 192)
# PREVENTS A TYPING VALUE IN COMBO BOX
projects_combo_box['state'] = 'readonly'
# START OF CONTRACT LABEL
start_of_contract = Label(window, text = "Start of Contract", font = ('Arial', 12), bg = 'white')
start_of_contract.place(x = 30, y = 261)
# START OF CONTRACT DATE TIME PICKER
start_of_contract_date = DateEntry(window, selectmode = 'day', year = 2022, month = 1, day = 1, cursor = 'hand2',
font = ('Arial', 12), width = 28, textvariable = contractStart)
start_of_contract_date.place(x = 34, y = 299)
# END OF CONTRACT LABEL
end_of_contract = Label(window, text = "End of Contract", font = ('Arial', 12), bg = 'white')
end_of_contract.place(x = 30, y = 362)
# END OF CONTRACT DATE TIME PICKER
end_of_contract_date = DateEntry(window, selectmode = 'day', year = 2022, month = 1, day = 1, cursor = 'hand2',
font = ('Arial', 12), width = 28, textvariable = contractEnd)
end_of_contract_date.place(x = 34, y = 400)
# STATUS LABEL
status = Label(window, text = "Positions", font = ('Arial', 12), bg = 'white')
status.place(x = 30, y = 464)
# STATUS OPTIONS
status_options = ['Active', 'Inactive', 'Terminated', 'Blacklisted']
# STATUS COMBOBOX
status_combo_box = Combobox(window, values = status_options, width = 28, font = ('Arial', 12), cursor = 'hand2', textvariable = stat)
status_combo_box.place(x = 34, y = 500)
# PREVENTS A TYPING VALUE IN COMBO BOX
status_combo_box['state'] = 'readonly'
# SAVE BUTTON
save = Button(window, text = "Save", font = ('Arial', 12), padx = 43, pady = 5, cursor = 'hand2', bg = 'green', fg = 'white', bd = 0,
activebackground = 'green', activeforeground = 'white', command = addData)
save.place(x = 34, y = 573)
# EDIT BUTTON
edit = Button(window, text = "Edit", font = ('Arial', 12), padx = 45, pady = 5, cursor = 'hand2', bg = 'orange', fg = 'white',
activebackground = 'orange', activeforeground = 'white', bd = 0)
edit.place(x = 180, y = 573)
# DELETE BUTTON
delete = Button(window, text = "Delete", font = ('Arial', 12), padx = 45, pady = 5, cursor = 'hand2', bg = 'red', fg = 'white',
activebackground = 'red', activeforeground = 'white', bd = 0)
delete.place(x = 93, y = 648)
# CONNECTION BUTTON
connection_button = Button(window, text = "Check Stat", font = ('Arial', 12), padx = 10, pady = 5, cursor = 'hand2', bg = 'blue', fg = 'white',
activebackground = 'blue', activeforeground = 'white', bd = 0, command = databaseConnection)
connection_button.place(x = 1064, y = 648)
# SEARCH LABEL
search = Label(window, text = "Search", font = ('Arial', 12), bg = 'white')
search.place(x = 878, y = 44)
# SEARCH ENTRY
search_entry = Entry(window, font = ('Arial', 12), width = 15, highlightbackground = 'gray', highlightcolor = 'black',
highlightthickness = 1, bd = 0)
search_entry.place(x = 966, y = 41)
# Create Treeview Frame
tree_frame = Frame(window)
tree_frame.pack(pady=20)
# Treeview Scrollbar
tree_scroll = Scrollbar(tree_frame)
tree_scroll.pack(side=RIGHT, fill=Y)
# Create Treeview
my_tree = ttk.Treeview(tree_frame, yscrollcommand=tree_scroll.set, selectmode="extended")
# Pack to the screen
my_tree.pack(side= LEFT)
#Configure the scrollbar
tree_scroll.config(command=my_tree.yview)
# Define Our Columns
my_tree['columns'] = ("SRID", "fullname", "projects", "startofcontract", "endofcontract", "status")
# Formate Our Columns
my_tree.column("#0", width=0, stretch=NO)
my_tree.column("SRID", anchor=W, width=140)
my_tree.column("fullname", anchor=CENTER, width=100)
my_tree.column("projects", anchor=W, width=140)
my_tree.column("startofcontract", anchor=CENTER, width=140)
my_tree.column("endofcontract", anchor=W, width=140)
my_tree.column("status", anchor=CENTER, width=140)
# Create Headings
my_tree.heading("#0", text="", anchor=W)
my_tree.heading("SRID", text="SRID", anchor=W)
my_tree.heading("fullname", text="FullName", anchor=CENTER)
my_tree.heading("projects", text="Projects", anchor=W)
my_tree.heading("startofcontract", text = "Start", anchor=W)
my_tree.heading("endofcontract", text = "End", anchor=W)
my_tree.heading("status", text = "Status", anchor=W)
window.mainloop()
mainWindow()
I have a small notepad that I'm creating for myself.
However, in the section of "Troubleshooting Steps" I have a TTK.text that is takint a wide column. Now I need to add two buttons underneath. "Save" and "Clear"
The "save" button shows center under the TEXT box. (Expected) but when I try to add "Clear" next to "Save" it is displayed in a different column way to the rigth.
Here is the code below.
from tkinter import *
from tkinter import ttk
from tkinter import Text
class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Inbound Mail")
self.pack(fill=BOTH, expand=True)
frame = LabelFrame(self, text = "CUSTOMER INFORMTION ")
frame.grid(row =0, column = 0, pady = 20, padx = 10)
case_number = Label(frame, text = "Case Number ")
case_number.grid(row = 0, column = 0, pady = 3, padx = 3)
self.case_entry = Entry(frame, width = 30)
self.case_entry.grid(row = 0, column = 1, pady = 5)
customer_name = Label(frame, text = "Contact Name ")
customer_name.grid(row =1, column = 0, pady = 3, padx = 3)
self.name_entry = Entry(frame, width = 30)
self.name_entry.grid(row = 1, column = 1)
customer_phone = Label(frame, text = "Phone Number ")
customer_phone.grid(row =2, column = 0, pady = 3, padx = 3)
self.phone_entry = Entry(frame, width = 30)
self.phone_entry.grid(row = 2, column = 1)
customer_email = Label(frame, text = "Email Address ")
customer_email.grid(row =3, column = 0, pady = 3, padx = 3)
self.email_entry = Entry(frame, width = 30)
self.email_entry.grid(row = 3, column = 1)
Label(frame, text = "Product").grid(row = 4, column = 0, pady = 3, padx = 3)
self.product = ttk.Combobox(frame,
values = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8"], width = 27)
self.product.grid(row = 4, column = 1, pady = 3, padx = 3)
self.product.current(0)
#ISSUE DESCRIPTION
frame2 = LabelFrame(self, text = "ISSUE")
frame2.grid(row = 5 , column = 0, pady = 20, padx = 10)
Label(frame2, text = "ISSUE DESCRIPTION").grid(row = 6, column = 0, pady = 3, padx = 3)
self.issue = Entry(frame2, width = 55)
self.issue.grid(row = 7, column = 0, pady = 3, padx = 3)
# TROUBLESHOOTING STEPS
frame3 = LabelFrame(self, text = "TROUBLESHOOTING STEPS")
frame3.grid(row = 8, column = 0)
self.troubles = Text(frame3, height = 15, width = 40, wrap = WORD)
self.troubles.grid(row = 9, column = 0,padx = 10, pady = 10)
#SCROLLBAR FOR TEXT
scroll = Scrollbar(self, command = self.troubles.yview)
scroll.grid(row = 8, column = 1, sticky = "nsew")
self.troubles.config(yscrollcommand = scroll.set)
#SAVE BUTTON AND CLEAR BUTTON.
self.save = Button(frame3, text = "Save")
self.save.grid(row = 10, column = 0)
def main():
root = Tk()
app = Example()
root.geometry("380x650")
# root.resizable(False, False)
root.mainloop()
if __name__ == '__main__':
main()
Make another small Frame to act as a container for the Buttons. You may also want to know that a scrolled Text widget is part of standard tkinter, you don't have to reinvent that. Just add this import:
from tkinter.scrolledtext import ScrolledText
And then:
# TROUBLESHOOTING STEPS
frame3 = LabelFrame(self, text = "TROUBLESHOOTING STEPS")
frame3.grid(row = 8, column = 0)
self.troubles = ScrolledText(frame3, height = 15, width = 40, wrap = WORD)
self.troubles.grid(row = 9, column = 0,padx = 10, pady = 10)
#SAVE BUTTON AND CLEAR BUTTON.
buttonframe = Frame(frame3)
buttonframe.grid(row = 10, column = 0)
self.save = Button(buttonframe, text = "Save")
self.save.pack(side=LEFT)
self.clear = Button(buttonframe, text = "Clear")
self.clear.pack(side=LEFT)
I've made a simple gui age converter app but i want to change its bg color to black.
The problem is in the ttk frame.i don't know how to configure its bg color.
I have tried different methods but that didn't work.
i would be grateful if you guys could help.
here is the code
from tkinter import *
from tkinter import ttk
from PIL import Image
def calculate(*args):
try:
age_sec = int(age.get())
age_sec = age_sec * 12 * 365 * 24 * 60 * 60
age_seconds.set(age_sec)
except:
age_seconds.set('Either the field is empty or \n value is not numeric.')
root = Tk()
root.title("Converter")
root.configure(background="black")
mainframe = ttk.Frame(root, padding = "6 6 12 12")
mainframe.grid(column = 0, row = 0, sticky = (N, W, E, S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
#mainframe['borderwidth'] = 2
#mainframe['relief'] = 'groove'
age = StringVar()
age_seconds = StringVar()
ttk.Label(mainframe, foreground = "#4D4E4F", text = "Enter your Age: ").grid(column = 1, row = 1, sticky = E)
age_entry = ttk.Entry(mainframe, width = 30, textvariable = age)
age_entry.grid(column = 2, row = 1, sticky = (W, E))
ttk.Label(mainframe, foreground = "#4D4E4F", text = "your age in seconds is ").grid(column = 1, row = 2, sticky = (E))
ttk.Label(mainframe, textvariable = age_seconds, background = "lightyellow", foreground = "#727475", width = 30).grid(column = 2, row = 2, sticky = W)
#Mouse Events...\\
butt_image = PhotoImage(file = 'images.gif')
ttk.Button(mainframe, compound = TOP, text = "Hit Now", image =butt_image, cursor = "hand2", width= 30, command = calculate).grid(column = 2, row = 4, sticky = W)
l2 = ttk.Label(mainframe,foreground = "#4D4E4F", text = "Mouse Events: ").grid(column = 1, row = 3, sticky = E)
l = ttk.Label(mainframe,background = "lightyellow", foreground = "#727475", text = 'Measurement is starting...', width = 30)
l.grid(column = 2, row = 3, sticky = W)
l.bind('<Enter>', lambda e: l.configure(text = 'Moved Mouse Inside'))
l.bind('<Leave>', lambda e: l.configure(text = 'Mouse Moved Out'))
l.bind('<1>', lambda e: l.configure(text = 'left Mouse clicked'))
l.bind('<Double-1>', lambda e: l.configure(text = 'Double clicked'))
l.bind('<B1-Motion>', lambda e: l.configure(text = 'Left button drag to %d, %d' %(e.x, e.y)))
image = PhotoImage(file = 'waves.gif')
ttk.Label(mainframe, compound = CENTER, text = "Image text", font = ('roman', 9, 'normal'), foreground ='green', image = image).grid(column = 3, row = 1, sticky = (N, E))
#if '__name__' == '__main__':
for child in mainframe.winfo_children(): child.grid_configure(padx = 15, pady = 15)
age_entry.focus()
root.bind('<Return>', calculate)
root.mainloop()
A ttk.Frame does not have a background / bg option. To change it you need to use style.
See ttk.Frame Info
If you don't really need to use a ttk.Frame you can just switch to a tkinter.Frame
I have been using tkinter's grid geometry manager and have configured all the rows and columns to weight = 1. The problem comes when I try to resize a Tk() window. When I resize it vertically only, the width of widgets and the proportion of column widths also change despite their equal weight. Furthermore, the width of the columns isn't in the desired proportions (i.e. all equal) before doing any resizing - to be precise the first column (with labels and buttons) is as wide as other two (holding a canvas with columnspan = 2 and two labels).
I think the problem is somehow connected to the PiSimulator._adjust_sizes function which dynamically changes the font or to the use of the canvas with a columnspan of 2.
Here's my code:
import tkinter as tk
from tkinter import font
class PiSimulator(tk.Frame):
def __init__(self, root, **kwargs):
super(PiSimulator, self).__init__(root, **kwargs)
self.root = root
self.root.title = 'Crtac krugova'
self.root.minsize(width = 600, height = 400)
self.pack(fill = 'both', expand = 1)
self.custom_font = font.Font(size = 20)
self.bind('<Configure>', self._adjust_sizes)
self.populate()
return
def populate(self):
tk.Label(self, text = 'Radijus:', font = self.custom_font, relief = 'raised',\
fg = 'green').grid(sticky='nswe', row = 0, column = 0)
self.radius = tk.IntVar()
tk.Spinbox(self, from_ = 1, to = 16, font = self.custom_font, textvariable = self.radius).grid(row = 1, column = 0)
tk.Label(self, text = 'Greška', font = self.custom_font, relief = 'raised', anchor='w',\
padx = 5, pady = 5, fg = 'green').grid(sticky='nswe', row = 0, column = 1)
self.error = tk.DoubleVar(0.0)
tk.Label(self, textvariable = self.error, font = self.custom_font, relief = 'raised',\
anchor='e', pady = 5, fg = 'green').grid(row = 0, column = 2, sticky='nswe')
self.canvas = PiCanvas(self, highlightthickness = 0)
self.canvas.grid(row = 1, rowspan = 5, column = 1, columnspan = 2, padx = 5, pady = 5, sticky='nswe')
tk.Button(self, text = 'Nacrtaj', font = self.custom_font, command = lambda: self.canvas.draw(self.radius.get())).grid(\
column = 0, row = 2, sticky='nswe')
tk.Button(self, text = 'Izbriši', font = self.custom_font, command = self.canvas.clear ).grid(\
column = 0, row = 3, sticky='nswe')
tk.Label(self, text = 'POVRŠINA', relief = 'groove', font = self.custom_font).grid(column = 0, row = 4, sticky='nswe')
self.area = tk.IntVar(0)
tk.Label(self, textvariable = self.area, relief = 'groove', font = self.custom_font).grid(column = 0, row = 5, sticky='nswe')
for i in range(3):
self.columnconfigure(i, weight = 1)
for i in range(6):
self.rowconfigure(i, weight = 1)
return
def _adjust_sizes(self, event):
new_font = int(event.height/15) - 2
self.custom_font.configure(size = new_font)
return
class PiCanvas(tk.Canvas):
def __init__(self, root, **kwargs):
super(PiCanvas, self).__init__(root, background = 'white', relief = 'groove', **kwargs)
self.root = root
self.cubes = []
self.circle = None
def draw(self, radius):
self.clear()
c_width = self.winfo_width()
c_height = self.winfo_height()
self.grid_side = int(min([c_width, c_height]))
self.grid_side-= 10
self.v_offset = (c_height - self.grid_side)/2
self.h_offset = (c_width - self.grid_side)/2
self.cube_side = self.grid_side/(2*radius)
vertix_coord = lambda x, x_cor, y_cor: x_cor*self.h_offset+y_cor*self.v_offset+x*self.cube_side
for i in range(2*radius):
new_line = []
for j in range(2*radius):
cube = self.create_rectangle(vertix_coord(i, 1, 0), vertix_coord(j, 0, 1),\
vertix_coord(i+1, 1, 0), vertix_coord(j+1, 0, 1), tag = 'unused')
new_line.append(cube)
self.cubes.append(new_line)
self.circle = self.create_oval(vertix_coord(0,1,0), vertix_coord(0,0,1),\
vertix_coord(2*radius,1,0), vertix_coord(2*radius,0,1),width = 2)
self.color_border_cubes()
print(self.circle)
def color_border_cubes(self):
circle_coords = self.coords(self.circle)
print(circle_coords)
for i in self.cubes:
for j in i:
cube_coords = self.coords(j)
if self.circle in self.find_overlapping(*cube_coords) + self.find_enclosed(*circle_coords):
self.itemconfigure(j, fill = 'green')
def clear(self):
self.cubes = []
self.circle = None
self.delete('all')
return
root = tk.Tk()
a=PiSimulator(root)
root.mainloop()