Display Listbox with columns using Tkinter?

前端 未结 3 1354
心在旅途
心在旅途 2020-12-04 13:46

I\'m trying to create a Listbox in Tkinter that has columns.

I\'m returning from a DB query records and would like to display each entry in it\'s own c

相关标签:
3条回答
  • 2020-12-04 14:07

    Using TkTreectrl:

    import Tkinter as tk
    import TkTreectrl as treectrl
    import sqlite3
    
    def setup_table(connection):
        cursor=connection.cursor()
        cursor.execute('''CREATE TABLE foo
                          (id INTEGER PRIMARY KEY AUTOINCREMENT,
                          bar TEXT)''')
        sql='INSERT INTO foo (bar) values (?)'
        for i in range(10):
            cursor.execute(sql,(i,))
        cursor.execute(sql,(u'\N{INFINITY}',))
    
    def select_cmd(selected):
        print 'Selected items:', selected
    
    def main():
        connection=sqlite3.connect(':memory:')   
        setup_table(connection)
        cursor=connection.cursor()
    
        root = tk.Tk()
        root.title('Simple MultiListbox demo')
        mlb = treectrl.MultiListbox(root)
        mlb.pack(side='top', fill='both', expand=1)
        tk.Button(root, text='Close', command=root.quit).pack(side='top', pady=5)
        mlb.focus_set()   
        mlb.configure(selectcmd=select_cmd, selectmode='extended')
        mlb.config(columns=('Column 1', 'Column 2'))
        cursor.execute('SELECT * from foo')
        for row in cursor.fetchall():
            mlb.insert('end',*map(unicode,row))
        root.mainloop()
    
    if __name__=='__main__':
        main()
    

    yields

    enter image description here

    0 讨论(0)
  • 2020-12-04 14:07

    You can use Ttk/Tkinker Treeview widget, which is used to work with tabular data.

    The following is an example of a class that uses a Treeview widget to display a multi-column list of strings:

    '''
    Here the TreeView widget is configured as a multi-column listbox
    with adjustable column width and column-header-click sorting.
    '''
    try:
        import Tkinter as tk
        import tkFont
        import ttk
    except ImportError:  # Python 3
        import tkinter as tk
        import tkinter.font as tkFont
        import tkinter.ttk as ttk
    
    class MultiColumnListbox(object):
        """use a ttk.TreeView as a multicolumn ListBox"""
    
        def __init__(self):
            self.tree = None
            self._setup_widgets()
            self._build_tree()
    
        def _setup_widgets(self):
            s = """\click on header to sort by that column
    to change width of column drag boundary
            """
            msg = ttk.Label(wraplength="4i", justify="left", anchor="n",
                padding=(10, 2, 10, 6), text=s)
            msg.pack(fill='x')
            container = ttk.Frame()
            container.pack(fill='both', expand=True)
            # create a treeview with dual scrollbars
            self.tree = ttk.Treeview(columns=car_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 car_header:
                self.tree.heading(col, text=col.title(),
                    command=lambda c=col: sortby(self.tree, c, 0))
                # adjust the column's width to the header string
                self.tree.column(col,
                    width=tkFont.Font().measure(col.title()))
    
            for item in car_list:
                self.tree.insert('', 'end', values=item)
                # adjust column's width if necessary to fit each value
                for ix, val in enumerate(item):
                    col_w = tkFont.Font().measure(val)
                    if self.tree.column(car_header[ix],width=None)<col_w:
                        self.tree.column(car_header[ix], width=col_w)
    
    def sortby(tree, col, descending):
        """sort tree contents when a column header is clicked on"""
        # grab values to sort
        data = [(tree.set(child, col), child) \
            for child in tree.get_children('')]
        # if the data to be sorted is numeric change to float
        #data =  change_numeric(data)
        # now sort the data in place
        data.sort(reverse=descending)
        for ix, item in enumerate(data):
            tree.move(item[1], '', ix)
        # switch the heading so it will sort in the opposite direction
        tree.heading(col, command=lambda col=col: sortby(tree, col, \
            int(not descending)))
    
    # the test data ...
    
    car_header = ['car', 'repair']
    car_list = [
    ('Hyundai', 'brakes') ,
    ('Honda', 'light') ,
    ('Lexus', 'battery') ,
    ('Benz', 'wiper') ,
    ('Ford', 'tire') ,
    ('Chevy', 'air') ,
    ('Chrysler', 'piston') ,
    ('Toyota', 'brake pedal') ,
    ('BMW', 'seat')
    ]
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        root.title("Multicolumn Treeview/Listbox")
        listbox = MultiColumnListbox()
        root.mainloop()
    

    These are some pictures of the result of using a Treeview widget:

    enter image description here

    0 讨论(0)
  • 2020-12-04 14:28

    One simple solution is to use two listboxes side-by-side. There's no real magic, you just have to do a little bit of extra work to get one scrollbar to control both (easily done) and have the selection in the two sync up (also easily done).

    0 讨论(0)
提交回复
热议问题