Question

I'm currently having a little bit of an issue - I have a class called tableView, and what I'd really like is for it to be used like a normal widgit inside a TK() frame. I want to be able to call it by doing something like this -

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

And for it to distplay in my current tk() frame. Currently it pops up in a window of its own, and I was interested in finding out how I can add just add it to the current frame. I assume it must inherit from a widget, and use a parent value, somehow? How tricky is it to accomplish this? Is there an easily extendible class?

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

I'm relatively new to python, so any help is appreciated - also, is this a reasonable way of making a table - are there any better ways/libs already out there?

Thanks for your help Ollie

Était-ce utile?

La solution

Your TableView class needs to inherit from Frame. When you do that, you can treat it just like any other widget.

For example:

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

You don't need to create a container, because the object is its own container. Any child widgets within the class should be packed/gridded to self so that they are inside the container.

Also, you shouldn't call tk.Tk() anywhere except in your main program -- that is why you get a separate window.

Your main program goes virtually unchanged, except you need to add a line of code to place the widget in the grid:

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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top