亲爱的所有我一直在尝试使用Tkinter在子窗口中插入树视图,但由于我不知道如何将它们放在一起,因此它非常复杂。非常感谢你提前! Héctor
这是我到目前为止所做的:
import Tkinter
from Tkinter import *
import tkFont
import ttk
root= Tk()
class McListBox(object):
def __init__(self):
self.tree = None
self._setup_widgets()
self._build_tree()
def _setup_widgets(self):
s = """
"""
msg = ttk.Label(wraplength="4i", justify="right", anchor="n",
padding=(6, 6, 6, 6, 6 ,6), text=s)
msg.pack(fill='x')
container = ttk.Frame()
container.pack(fill='both', expand=True)
self.tree = ttk.Treeview(columns=element_header, show="headings")
vsb = ttk.Scrollbar(orient="vertical", command=self.tree.yview)
hsb = ttk.Scrollbar(orient="horizontal", command=self.tree.xview)
self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
self.tree.grid(column=0, row=0, sticky='nsew', in_=container)
vsb.grid(column=1, row=0, sticky='ns', in_=container)
hsb.grid(column=0, row=1, sticky='ew', in_=container)
container.grid_columnconfigure(0, weight=1)
container.grid_rowconfigure(0, weight=1)
def _build_tree(self):
for col in element_header:
self.tree.heading(col, text=col.title(),
command=lambda c=col: sortby(self.tree, c, 0))
self.tree.column(col, width=tkFont.Font().measure(col.title()))
for item in element_list:
self.tree.insert('', 'end', values=item)
for ix, val in enumerate(item):
col_w = tkFont.Font().measure(val)
if self.tree.column(element_header[ix], width=None) < col_w:
self.tree.column(element_header[ix], width=col_w)
def isnumeric(s):
for c in s:
if c in "0000123456789000-.":
numeric = True
else:
return False
return numeric
def change_numeric(data):
new_data = []
if isnumeric(data[0][0]):
for child, col in data:
new_data.append((float(child), col))
return new_data
return data
def sortby(tree, col, descending):
data = [(tree.set(child, col), child) for child in tree.get_children('')]
data = change_numeric(data)
data.sort(reverse=descending)
for ix, item in enumerate(data):
tree.move(item[1], '', ix)
tree.heading(col,
command=lambda col=col: sortby(tree, col, int(not descending)))
element_header = ["Device", "Type", "LETs Threshold (L0)"]
element_list = [('93L422', 'Bipolar', '0.6')]
mc_listbox = McListBox()
def Child_Window():
win2 = Toplevel()
message = "This is the child window"
Label(win2, text=message).pack()
Button(win2, text='OK', command=win2.destroy).pack()
Button(root, text='Bring up Message', command=Child_Window).pack()
root.mainloop()
答案 0 :(得分:2)
应该使用父窗口作为第一个参数构造Treeview。我更改了Child_Window方法,以便显示非常简单的树。您现在可以轻松地将树调整为我的示例。我还建议以所有方法都包含在McListBox类中的方式重构代码。我使用了包几何管理器而不是网格管理器。这是我的例子:
def Child_Window():
win2 = Toplevel()
message = "This is the child window"
Label(win2, text=message).pack()
element_header=['1st','2nd','3rd']
treeScroll = ttk.Scrollbar(win2)
treeScroll.pack(side=RIGHT, fill=Y)
tree = ttk.Treeview(win2,columns=element_header, show="headings", yscrollcommand = treeScroll)
tree.heading("1st", text="1st")
tree.pack(side=LEFT, fill=BOTH)
treeScroll.config(command=tree.yview)
在与Hector讨论之后,我决定粘贴所有修改后的类,它们应该像所需的那样工作。顺便说一句,我重构它,以便所有函数和变量都是类的成员。适用于Python 2.7.5。
import Tkinter
from Tkinter import *
import tkFont
import ttk
class ModifiedMcListBox(object):
def __init__(self):
self.root= Tk()
self.tree = None
self.element_header = ["Device", "Type", "LETs Threshold (L0)"]
self.element_list = [('93L422', 'Bipolar', '0.6')]
self._setup_widgets()
self._build_tree()
self.root.mainloop()
def _setup_widgets(self):
s = """
"""
msg = ttk.Label(wraplength="4i", justify="right", anchor="n",
padding=(6, 6, 6, 6, 6 ,6), text=s)
msg.pack(fill='x')
container = ttk.Frame()
container.pack(fill='both', expand=True)
self.tree = ttk.Treeview(columns=self.element_header, show="headings")
vsb = ttk.Scrollbar(orient="vertical", command=self.tree.yview)
hsb = ttk.Scrollbar(orient="horizontal", command=self.tree.xview)
self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
self.tree.grid(column=0, row=0, sticky='nsew', in_=container)
vsb.grid(column=1, row=0, sticky='ns', in_=container)
hsb.grid(column=0, row=1, sticky='ew', in_=container)
container.grid_columnconfigure(0, weight=1)
container.grid_rowconfigure(0, weight=1)
Button(self.root, text='Bring up Message', command=self.Child_Window).pack()
def _build_tree(self):
for col in self.element_header:
self.tree.heading(col, text=col.title(),
command=lambda c=col: self.sortby(self.tree, c, 0))
self.tree.column(col, width=tkFont.Font().measure(col.title()))
for item in self.element_list:
self.tree.insert('', 'end', values=item)
for ix, val in enumerate(item):
col_w = tkFont.Font().measure(val)
if self.tree.column(self.element_header[ix], width=None) < col_w:
self.tree.column(self.element_header[ix], width=col_w)
def isnumeric(self,s):
for c in s:
if c in "0000123456789000-.":
numeric = True
else:
return False
return numeric
def change_numeric(self,data):
new_data = []
if self.isnumeric(data[0][0]):
for child, col in data:
new_data.append((float(child), col))
return new_data
return data
def sortby(self,tree, col, descending):
data = [(tree.set(child, col), child) for child in tree.get_children('')]
data = self.change_numeric(data)
data.sort(reverse=descending)
for ix, item in enumerate(data):
tree.move(item[1], '', ix)
tree.heading(col,
command=lambda col=col: sortby(tree, col, int(not descending)))
def Child_Window(self):
win2 = Toplevel()
message = "This is the child window"
Label(win2, text=message).pack()
new_element_header=['1st','2nd','3rd']
treeScroll = ttk.Scrollbar(win2)
treeScroll.pack(side=RIGHT, fill=Y)
tree = ttk.Treeview(win2,columns=new_element_header, show="headings", yscrollcommand = treeScroll)
tree.heading("1st", text="1st")
tree.heading("2nd", text="2nd")
tree.heading("3rd", text="3rd")
tree.pack(side=LEFT, fill=BOTH)
treeScroll.config(command=tree.yview)
mc_listbox = ModifiedMcListBox()
答案 1 :(得分:1)
解决方案很简单:每个小部件都将另一个小部件作为其第一个参数,此参数定义新小部件的父级。默认情况下,当您使用pack
,grid
或place
时,新窗口小部件将显示在专利窗口小部件中。这真的是你需要知道的全部。
因此,如果您希望self.tree
位于win2
中,则win2
必须*作为第一个参数提供给treeview构造函数。
请注意,您无法在一个窗口中创建窗口小部件,然后将其移动到另一个窗口(“窗口”定义为“Tk
或Toplevel
的实例”。窗口及其父窗口必须与祖先共享最顶层的窗口小部件。
*“必须”有点过于强大,因为您可以将小部件显示在小组件中,而不是直接父级。我不认为这与你在这里要做的事情有关,所以我不会详细说明避免混淆。