canvas 上的树视图框架

Treeview frame on canvas

这段代码有两个问题:
1.我无法让树视图框架填满整个canvas(垂直)
2.不想显示第一列
我该如何解决这些问题?

import os

import time
import datetime
from datetime import timedelta
from tkinter.constants import TRUE

try:
    import Tkinter as tk
    import tkFont
    import ttk

    from Tkconstants import CENTER, LEFT, N, E, W, S
    from Tkinter import StringVar
except ImportError: # py3k
    import tkinter as Tkinter
    import tkinter.font as tkFont
    import tkinter.ttk as ttk

    from tkinter.constants import CENTER, LEFT, N, E, W, S
    from tkinter import StringVar

GRID_BORDER_WIDTH = "1"

def populate_treeview(frame, my_column_headers, my_list):

    style = ttk.Style()
    style.configure("mystyle.Treeview", highlightthickness=0, bd=0, font=('Calibri', 11)) # Modify the font of the body
    style.configure("mystyle.Treeview.Heading", font=('Calibri', 13,'bold')) # Modify the font of the headings
    style.layout("mystyle.Treeview", [('mystyle.Treeview.treearea', {'sticky': 'nswe'})]) # Remove the borders

    tree=ttk.Treeview(frame, style="mystyle.Treeview") # create the widget

    tree["columns"]=my_column_headers
    for i in range (0,26):
        tree.column(my_column_headers[i], width=50, minwidth=20, stretch=Tkinter.YES)

    for i in range (0,26):
        tree.heading(my_column_headers[i] ,text=my_column_headers[i], anchor=Tkinter.W)

    PARENT="" # top level
    i = 0
    for item in my_list:
        #print ("item: " + str(item)) 
        tree.insert(PARENT, i, i, text=str(i), values=(item))
        i += 1

    tree.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=TRUE)

def OnFrameConfigure(canvas):
    '''Reset the scroll region to encompass the inner frame'''
    canvas.configure(scrollregion=canvas.bbox("all"))

def OnCanvasConfigure(self, event):
    width = 0
    for child in self.sensorsStatsFrame.grid_slaves():
        width += child.winfo_reqwidth()

    self.canvas.itemconfigure(self.canvas_frame, width=width, height=event.height)

# main ########################################################################
def main():

    print ("[DEBUG]***  Display Test***)\n");

    # Data
    item_column_headers =  ["a", "b", "c", "d","e", "f", "g", "h","i", "j", "k", "l","m", "n", "o", "p","q", "r", "s", "t", "u","v", "w", "x", "y", "z"]
    item_list = []
    for row_number in range (0,50):
        row = []
        for alpha in item_column_headers:
            row.append (str(row_number) + alpha)
        item_list.append(row)

    print (item_list)

    ## GUI ------------------------------------------------------------------------------

    root = Tkinter.Tk()

    canvas = Tkinter.Canvas(root, borderwidth=6, background="#222222" )

    frame = Tkinter.Frame(canvas, background="#ff0000", borderwidth = 5)
    frame.pack(side=Tkinter.TOP, expand=1, fill=Tkinter.BOTH)
    canvas.create_window((0,0), window = frame, anchor="nw", tags="my_tag")
    canvas.bind("<Configure>", lambda event,  root=root:OnCanvasConfigure(root))

    verticalScrollbar = Tkinter.Scrollbar(root, orient="vertical", command=canvas.yview)
    canvas.configure(yscrollcommand=verticalScrollbar.set)
    verticalScrollbar.pack(side="right", fill="y", expand=0)

    horizontalScrollbar = Tkinter.Scrollbar(root, orient="horizontal", command=canvas.xview)
    canvas.configure(xscrollcommand=horizontalScrollbar.set)
    horizontalScrollbar.pack(side="bottom", fill="x", expand=0)

    canvas.pack(fill="both", expand=1)

    frame.bind("<Configure>", lambda event, canvas=canvas: OnFrameConfigure(canvas))
    #frame.bind("<Configure>", OnFrameConfigure)

    populate_treeview(frame, item_column_headers, item_list) 

    root.geometry("1000x600")
    root.wm_title("Display Test")

    root.mainloop()

    print ("\n*** Done " + str(datetime.datetime.now()) + "  - Display Test ***");

# main ###############################################################################

if __name__ == "__main__":
    # stuff only to run when not called via 'import' here
    main()

这是包含@BryanOakley 建议的修复程序的代码

import os

import time
import datetime
from datetime import timedelta
from tkinter.constants import TRUE

try:
    import Tkinter as tk
    import tkFont
    import ttk

    from Tkconstants import CENTER, LEFT, N, E, W, S
    from Tkinter import StringVar
except ImportError: # py3k
    import tkinter as Tkinter
    import tkinter.font as tkFont
    import tkinter.ttk as ttk

    from tkinter.constants import CENTER, LEFT, N, E, W, S
    from tkinter import StringVar

GRID_BORDER_WIDTH = "1"

def populate_treeview(frame, my_column_headers, my_list):

    style = ttk.Style()
    style.configure("mystyle.Treeview", highlightthickness=0, bd=0, font=('Calibri', 11)) # Modify the font of the body
    style.configure("mystyle.Treeview.Heading", font=('Calibri', 13,'bold')) # Modify the font of the headings
    style.layout("mystyle.Treeview", [('mystyle.Treeview.treearea', {'sticky': 'nswe'})]) # Remove the borders

    tree=ttk.Treeview(frame, style="mystyle.Treeview") # create the widget

    vsb = ttk.Scrollbar(tree, orient="vertical", command=tree.yview)
    vsb.configure(command=tree.yview)
    vsb.pack(side='right', fill='y')
    tree.configure(yscrollcommand=vsb.set)

    hsb = ttk.Scrollbar(tree, orient="horizontal", command=tree.xview)
    hsb.configure(command=tree.xview)
    hsb.pack(side='bottom', fill='x')
    tree.configure(xscrollcommand=hsb.set)

    tree["columns"]=my_column_headers

    for i in range (0,26):
        tree.column(my_column_headers[i], width=50, minwidth=20, stretch=Tkinter.YES)

    for i in range (0,26):
        tree.heading(my_column_headers[i] ,text=my_column_headers[i], anchor=Tkinter.W)

    PARENT="" # top level
    i = 0
    for item in my_list:
        #print ("item: " + str(item)) 
        tree.insert(PARENT, i, i, text=str(i), values=(item))
        i += 1

    tree["show"] = ["headings"]        
    tree.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=TRUE)

# main ########################################################################
def main():

    print ("[DEBUG]***  Display Test***)\n");

    # Data
    item_column_headers =  ["a", "b", "c", "d","e", "f", "g", "h","i", "j", "k", "l","m", "n", "o", "p","q", "r", "s", "t", "u","v", "w", "x", "y", "z"]
    item_list = []
    for row_number in range (0,50):
        row = []
        for alpha in item_column_headers:
            row.append (str(row_number) + alpha)
        item_list.append(row)

    ## GUI ------------------------------------------------------------------------------

    root = Tkinter.Tk()

    frame = Tkinter.Frame(root, background="#ff0000", borderwidth = 5)
    frame.pack(side=Tkinter.TOP, expand=1, fill=Tkinter.BOTH)

    populate_treeview(frame, item_column_headers, item_list) 

    root.geometry("1000x600")
    root.wm_title("Display Test")

    root.mainloop()

    print ("\n*** Done " + str(datetime.datetime.now()) + "  - Display Test ***");

# main ###############################################################################

if __name__ == "__main__":
    # stuff only to run when not called via 'import' here
    main()

I can't get the treeview frame to fill the entire canvas (vertically)

树没有填满 canvas 的问题是因为它在一个框架中,而框架没有填满 canvas。看起来你正试图在你的 OnCanvasConfigure 方法中解决这个问题,但是有很多错误阻止它工作。

首先,你有一个迭代 self.sensorsStatsFrame.grid_slaves() 的循环,但是你没有定义 self 并且没有名为 sensorsStatsFrame 的小部件,所以这个函数在它得到之前会失败有机会改变框架的高度。因为这段代码会抛出错误,所以函数中的后续代码不会 运行.

接下来,您尝试调用 self.canvas.configure,但同样没有 selfself.canvas,因此该语句将失败。您还使用 self.canvas_frame,但同样,它不存在,因此代码将失败。

如果您解决了所有这些问题,代码应该允许将框架配置为与 canvas 相同的宽度和高度,从而解决您提出的第一个问题。

I don't want the first column to be displayed

treeview 属性 show 允许您定义要显示树的哪些部分。您为其分配一个包含 "tree" and/or "headings" 的列表。您不想看到第一列,它由 "tree" 表示。因此,要隐藏该值,您希望将 "headings" 作为列表中用于 show 属性的唯一值传递。

tree["show"] = ["headings"]