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
,但同样没有 self
和 self.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"]
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
,但同样没有 self
和 self.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"]