简体   繁体   English

使用 GUI 上的其他小部件调整 Canvas 小部件的大小

[英]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__() .由于ExcelTablecanvas内的内部框架,并且已经使用 canvas.create_window canvas.create_window(...)放置在canvas内,因此您不应在StartApp.__init__()内调用t1.grid(...) ) 。

Also you set the scrollregion of canvas wrong in the following line:此外,您在以下行中错误地设置了scrollregioncanvas区域:

canvas.configure(scrollregion=parent.bbox('all'))

It should be:它应该是:

canvas.configure(scrollregion=canvas.bbox('all'))

Finally you forgot to configure yscrollcommand option of canvas .最后你忘了配置canvasyscrollcommand选项。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM