画布上的树状视图框架

时间:2019-05-21 14:59:58

标签: python-3.x tkinter treeview tkinter-canvas

enter image description here此代码有2个问题:
1.我无法获得树形视图框架来垂直填充整个画布
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()

1 个答案:

答案 0 :(得分:2)

  

我无法获得树形视图框架来垂直填充整个画布

树没有填充画布的问题是因为它在框架中,而框架没有填充画布。看来您正在尝试通过OnCanvasConfigure方法解决该问题,但是有许多错误阻止了它的正常工作。

首先,您有一个循环遍历self.sensorsStatsFrame.grid_slaves()的循环,但是您尚未定义self并且没有名为sensorsStatsFrame的小部件,因此此函数在获得机会之前将失败更改框架的高度。由于此代码会引发错误,因此该函数中的任何后续代码都不会运行。

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

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

  

我不想显示第一列

通过treeview属性show,您可以定义要显示的树的哪些部分。您为其分配一个包含"tree"和/或"headings"的列表。您不想看到第一列,它由"tree"表示。因此,要隐藏该值,您要传递"headings"作为列表中用于show属性的唯一值。

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