1

亲爱的,我一直在尝试使用 Tkinter 在子窗口中插入树视图,但它非常复杂,因为我不知道如何将它们放在一起。非常感谢您!赫克托

这是我到目前为止所做的:

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()
4

2 回答 2

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()
于 2013-05-18T21:24:56.517 回答
1

解决方案很简单:每个小部件都将另一个小部件作为其第一个参数,该参数定义了新小部件的父级。当您使用或时pack,新的小部件默认会出现在专利小部件中。这就是你需要知道的一切。gridplace

因此,如果您想self.tree在 中win2win2必须将*作为第一个参数提供给 treeview 构造函数。

请注意,您不能在一个窗口中创建小部件然后将其移动到另一个窗口(其中“窗口”定义为“Tk或的实例Toplevel”)。窗口及其父窗口必须与祖先共享相同的最顶层小部件。

*“必须”有点太强了,因为你可以让小部件出现在小部件内部而不是它们的直接父级。我认为这与您在这里尝试做的事情无关,所以我不会详细说明以避免混淆。

于 2013-05-20T23:24:23.647 回答