使一个类成为一个小部件 - Tkinter

时间:2014-05-13 20:24:20

标签: python-3.x tkinter widget

我目前有一个问题 - 我有一个名为tableView的类,而我真正喜欢的是它像TK()帧中的普通widgit一样使用。我想通过做这样的事情来调用它 -

root = Tk()
root.wm_title("Main")
ttk.Button(root, text="Add new student").grid(row = 0, column = 0)
ttk.Button(root, text="Edit Student").grid(row = 0, column = 1)
ttk.Button(root, text="Edit Student").grid(row = 0, column = 2)


columns = ['ID', 'First Name', 'Last Name', 'Registration No']
rows = server.select("Student")
TableView(root, columns, rows)

root.mainloop()

让它在我当前的tk()框架中分散注意力。目前它弹出一个自己的窗口,我有兴趣了解如何添加只是添加到当前帧。我假设它必须从一个小部件继承,并使用父值,不知何故?完成这个有多棘手?有一个容易扩展的课程吗?

class TableView(object):
"""use a ttk.TreeView as a multicolumn ListBox"""

    def __init__(self, columns, rows):
        self.rows = rows
        self.columns = columns
        self.tree = None
        self._setup_widgets()
        self._build_tree()

    def _setup_widgets(self):

    container = ttk.Frame()
    container.pack(fill='both', expand=True)

    self.tree = ttk.Treeview(columns=self.columns, show="headings")

    self.tree.grid(column=0, row=0, sticky='nsew', in_=container)

    container.grid_columnconfigure(0, weight=1)
    container.grid_rowconfigure(0, weight=1)

    def _build_tree(self):
        for col in self.columns:
            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 self.rows:
        self.tree.insert('', 'end', values=item)

    def sortby(tree, col, descending):
        """sort tree contents when a column header is clicked on"""
        data = [(tree.set(child, col), child)
            for child in tree.get_children('')]

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


root = tk.Tk()
root.wm_title("Journeys")
c = tk.Canvas(root, height=-8, width=800)
c.pack()

我对python比较陌生,所以任何帮助都会受到赞赏 - 同样,这是一个合理的制作表格的方式 - 那里有更好的方法/库吗?

感谢您的帮助 奥利

1 个答案:

答案 0 :(得分:1)

您的TableView课程需要继承Frame。当您这样做时,您可以像对待任何其他小部件一样对待它。

例如:

class TableView(Frame):
    def __init__(self, parent, columns, rows):
        Frame.__init__(self, parent)
        self.columns = columns
        self.rows = rows
        ...
        self._setup_widgets()
        ...

    def setup_widgets(self):
        self.tree = ttk.Treeview(self, columns=self.columns, show="heading")
        self.tree.grid(column=0, row=0, sticky="nsew")
        ...

您不需要创建容器,因为该对象是它自己的容器。应该将类中的任何子窗口小部件打包/网格化为self,以便它们位于容器内。

此外,你不应该在主程序中的任何地方调用tk.Tk() - 这就是你得到一个单独窗口的原因。

您的主程序几乎没有变化,除了您需要添加一行代码以将小部件放置在网格中:

root = Tk()
root.wm_title("Main")
ttk.Button(root, text="Add new student").grid(row = 0, column = 0)
ttk.Button(root, text="Edit Student").grid(row = 0, column = 1)
ttk.Button(root, text="Edit Student").grid(row = 0, column = 2)


columns = ['ID', 'First Name', 'Last Name', 'Registration No']
rows = server.select("Student")

# create an instance of the TableView widget
tableview = TableView(root, columns, rows)

# ... and add it to the root window
tableview.grid(row=1, column=0, columnspan=3)

root.mainloop()