[英]Sizing the Canvas widget with other widgets on the GUI
I'm creating a GUI that has a spreadsheet-like interface which is wrapped with entry method to allow the person that uses the program to enter it as if it is on a spreadsheet.我正在创建一个 GUI,它有一个类似电子表格的界面,该界面用输入方法包装,以允许使用该程序的人输入它,就好像它在电子表格上一样。 This allows me much greater control over all the data and manipulate it for data analysis later.这使我可以更好地控制所有数据并在以后对其进行操作以进行数据分析。 However, I can't restrict the size of the canvas to allow the scrolling bar to take effect.但是,我不能限制画布的大小来让滚动条生效。 IE if I change the number of rows, the canvas will resize to that (along with column(s) changes too). IE 如果我更改行数,画布将调整为该值(以及列更改)。 I have other widgets within the GUI that isn't shown in the code but I'm just focusing on trying to force a size on the Canvas widget itself.我在 GUI 中还有其他未在代码中显示的小部件,但我只是专注于尝试在 Canvas 小部件本身上强制设置大小。
Is there a way for me to force the Canvas to stay within "width and height" size without having the rows and columns controlling the size of the Canvas?有没有办法让我强制 Canvas 保持在“宽度和高度”大小内,而不用控制 Canvas 的大小的行和列?
import tkinter as tk
from tkinter import *
from textwrap import fill
from datetime import date
#Instantiate the GUI
class StartApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
t1 = ExcelTable(self)
t1.grid(row = 0, columnspan=2, sticky = "N")
t2 = ProductWidget()
t2.grid(row=1, column=0,sticky="SW")
t3 = TotalTrucks()
t3.grid(row=1, column=1, sticky="nsew")
#Instantiate the layout for the excel-like table entry for the top
part of the GUI
class ExcelTable(tk.Frame):
def __init__(self, parent, width=500, height=500):
rows=20
columns=10
#label for each column in the table colHeaders = ["#", "Driver", "Tare", "Ticket #", "Location", "Product", "Gross", "Net", "Tons", "Date"]
# use black background so it "peeks through" to
# form grid lines
#tk.Frame.__init__(self, parent, background="black", width=150, height=200)
#attempt to create a scrollbar within a canvas
canvas = tk.Canvas(parent)
scrollbar = tk.Scrollbar(parent, orient="vertical", command=canvas.yview)
#contain the Frame within the canvas
tk.Frame.__init__(self, canvas)
#creates the widgets to behave like excel-like table for data entry
self._widgets = []
for row in range(rows):
current_row = []
for column in range(columns):
if row == 0: #create the headers for the spreadsheet widget, using the colHeaders array
if column == 0:
label = tk.Label(self, text = colHeaders[column], borderwidth=0, width = 4)
else:
label = tk.Label(self, text = colHeaders[column], borderwidth=0, width=10)
else:
if column == 0:
label = tk.Label(self, text = (row))
else:
label = tk.Entry(self, text="")
label.bind
label.grid(row=row, column=column, sticky="nsew", padx=1, pady=1)
current_row.append(label)
self._widgets.append(current_row)
for column in range(columns):
self.grid_columnconfigure(column, weight=1)
canvas.create_window(0,0,anchor='nw', window=self)
canvas.update_idletasks()
canvas.configure(scrollregion=parent.bbox('all'))
canvas.grid(row=0,column=0)
scrollbar.grid(row=0, column=1, sticky="ns")
def set(self, row, column, value):
widget = self._widgets[row][column]
widget.configure(text=value)
def key(event):
print ("key: {}".format(event.char))
#obtain and store values that are entered in the ExcelTable
def find_in_grid(frame, row, column):
for children in frame.children.values():
info = children.grid_info()
#note that rows and column numbers are stored as string
if info['row'] == str(row) and info['column'] == str(column):
return children
return None
class ProductWidget(tk.Frame):
def __init__(self):
tk.Frame.__init__(self, background="white")
self._widgets = []
label1 = tk.Label(self, text="Product")
label1.grid(row=0,column=0, sticky="nsew")
label2 = tk.Label(self, text="Total Tons")
label2.grid(row=0, column=1, sticky="nsew")
class TotalTrucks(tk.Frame):
def __init__(self):
tk.Frame.__init__(self, background="white" )
self._widgets = []
label1 = tk.Label(self, text="Total Trucks")
label1.grid(row=0, rowspan=2, column=0, sticky="nsew")
label2 = tk.Label(self, text="Today: ")
label2.grid(row=1, column=0, stick="nsew")
label3 = tk.Label(self, text="Last Week: ")
label3.grid(row=2, column=0, sticky="nsew")
label4 = tk.Label(self, text="Overall")
label4.grid(row=3, column=0, sticky="nsew")
if __name__ == "__main__":
currYear = date.today().year
startGUI = StartApp()
startGUI.title("Truck Log " + str(currYear))
startGUI.mainloop()
Since ExcelTable
is the internal frame inside canvas
and is already put inside canvas
using canvas.create_window(...)
, so you should not call t1.grid(...)
inside StartApp.__init__()
.由于ExcelTable
是canvas
内的内部框架,并且已经使用 canvas.create_window canvas.create_window(...)
放置在canvas
内,因此您不应在StartApp.__init__()
内调用t1.grid(...)
) 。
Also you set the scrollregion
of canvas
wrong in the following line:此外,您在以下行中错误地设置了scrollregion
的canvas
区域:
canvas.configure(scrollregion=parent.bbox('all'))
It should be:它应该是:
canvas.configure(scrollregion=canvas.bbox('all'))
Finally you forgot to configure yscrollcommand
option of canvas
.最后你忘了配置canvas
的yscrollcommand
选项。
Below is the changes required:以下是所需的更改:
...
class StartApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
t1 = ExcelTable(self)
### should not call t1.grid(...) since t1 has already put in canvas using canvas.create_window(...)
#t1.grid(row = 0, columnspan=2, sticky = "N")
t2 = ProductWidget()
t2.grid(row=1, column=0,sticky="SW")
t3 = TotalTrucks()
t3.grid(row=1, column=1, sticky="nsew")
...
class ExcelTable(tk.Frame):
def __init__(self, parent, width=500, height=500):
...
#canvas.configure(scrollregion=parent.bbox('all'))
canvas.configure(scrollregion=canvas.bbox('all'), width=self.winfo_width(),
yscrollcommand=scrollbar.set)
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.