Следующий код представляет собой фрагмент таблицы, изначально созданной из x cols и y строк;Я опустил код, касающийся добавления или удаления столбцов или строк. (функции onFrameConfigure и onCanvasConfigure были скопированы из ответа 8 января 16 января, опубликованного @ RDT2). Моя проблема: исходная таблица создана правильно. Но если я запрашиваю 15 столбцов и 10 строк, в корневом окне отображаются только первые 7 столбцов и первые 11 строк, что приводит к принудительной прокрутке, даже если для оставшихся строк и столбцов достаточно места. Поскольку, насколько мне известно, я нигде не ставлю никаких ограничений, я затрудняюсь объяснить и исправить это поведение.
#!/usr/bin/env python3
from tkinter import *
class Calc_Table(Frame):
def __init__(self, root, cols, rows):
Frame.__init__(self, root)
self.cols = cols
self.rows = rows
self.configure(bg='green')
self.grid(sticky=NSEW)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.hsb = Scrollbar(orient=HORIZONTAL)
self.hsb.grid(row = 1, column = 0, sticky = EW)
self.vsb = Scrollbar(orient=VERTICAL)
self.vsb.grid(row = 0, column = 1, sticky = NS)
self.canvas = Canvas(self, xscrollcommand = self.hsb.set, yscrollcommand = self.vsb.set, bg='yellow')
self.canvas.grid(row = 0, column = 0, sticky = NSEW)
self.canvas.grid_rowconfigure(0, weight = 1)
self.canvas.grid_columnconfigure(0, weight = 1)
self.canvas.bind("<Configure>", self.onCanvasConfigure)
self.hsb.config(command = self.canvas.xview)
self.vsb.config(command = self.canvas.yview)
self.table_frame = self.create_table(self.cols,self.rows)
self.table_frame.bind("<Configure>", self.onFrameConfigure)
self.window = self.canvas.create_window((0, 0), window = self.table_frame, anchor=NW)
self.canvas.config(scrollregion = self.canvas.bbox('all'))
def onFrameConfigure(self, event):
self.canvas.update_idletasks()
self.canvas.configure(scrollregion=self.canvas.bbox('all'))
def onCanvasConfigure(self, event):
minWidth = self.table_frame.winfo_reqwidth()
minHeight = self.table_frame.winfo_reqheight()
if self.canvas.winfo_width() >= minWidth:
newWidth = self.winfo_width()
self.hsb.grid_remove()
else:
newWidth = minWidth
self.hsb.grid()
if self.canvas.winfo_height() >= minHeight:
newHeight = self.winfo_height()
self.vsb.grid_remove()
else:
newHeight = minHeight
self.vsb.grid()
self.canvas.itemconfig(self.window, width=newWidth, height=newHeight)
def create_table(self, cols, rows): # create initial table
self.table_frame = Frame(self.canvas)
self.table_frame.grid(column = 0, row = 0, sticky = NSEW)
self.cols, self.rows = cols, rows
for c in range(self.cols):
for r in range(self.rows):
if c == 0 and r == 0:
self.lbl = Label(self.table_frame, width=6, height=1, bg="white",
text="? ? ?", relief=RAISED)
self.lbl.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
elif c == 0 and r != 0:
self.lbl = Label(self.table_frame, width=6, height=1, bg="white",
text=f"R{r}",relief=RAISED)
self.lbl.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
elif c != 0 and r == 0:
self.lbl = Label(self.table_frame, width=6, height=1, bg="white",
text=f"C{c}",relief=RAISED)
self.lbl.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
else:
self.txt =Text(self.table_frame, width=6, height=1, bg="white",
relief=SUNKEN)
self.txt.grid(column=c, row=r, padx=1, pady=1, sticky=NSEW)
for c in range(self.cols):
self.table_frame.grid_columnconfigure(c, weight=1)
for r in range(self.rows):
self.table_frame.grid_rowconfigure(r, weight=1
for slave in self.table_frame.grid_slaves():
slave.bind("<Button-1>", self.cmd)
return self.table_frame
def cmd(self, event):
print(event.widget.grid_info())
if __name__ == '__main__':
cols = int(input("How many columns? "))
assert isinstance(int(cols), int), "integers only, please"
rows = int(input("How many rows? "))
assert isinstance(int(rows), int), "integers only, please"
root = Tk()
root.geometry("+10+10")
root.title("Master Table")
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
my_table = Calc_Table(root, cols, rows)
root.mainloop()