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