I'm in the process of writing my first python program with a GUI just as practice. I have two listboxes that are packed in the same frame so they are side by side. I have one scroll bar and would like that one scrollbar to move both listboxes simultaneously since the data is related. Is this possible?

Keep in mind that this is my first program so if you have any tips please feel free to post them.

#!/usr/bin/python

from tkinter import *
import pickle

root = Tk()
root.title("Note Taker")
textframe = Frame(root)
listframe = Frame(root)

def Button1():
    global newWindow
    newWindow = Tk()
    newWindow.title("New Window")
    tframe = Frame(newWindow)
    global text1
    global text2
    text1 = Entry(newWindow)
    text2 = Entry(newWindow)
    add = Button(newWindow, text="Add", command = Add)
    add.grid(row=3, column=1)
    text1.grid(row=0, column=1)
    text2.grid(row=1, column=1)
    itemName = Label(newWindow, text="Item Name")
    itemName.grid(row=0, column=0)
    numItem = Label(newWindow, text="Number of Items")
    numItem.grid(row=1, column=0)
    newWindow.mainloop()

def Add():
    text1_contents = text1.get()
    text2_contents = text2.get()
    namebox.insert(END, text1_contents)
    numbox.insert(END, text2_contents)
    text1.delete(0,END)
    text2.delete(0,END)
    newWindow.destroy()
    
def Button3():
    text_contents = text.get()
    namebox.insert(END, text_contents)
    text.delete(0,END)

def ReturnInsert(event):
    Button3()

def DeleteCurrent(event):
    listbox.delete(ANCHOR)

def CopyToText(event):
    text.delete(0,END)
    current_note = listbox.get(ANCHOR)
    text.insert(0, current_note)

def Save():
    f= file("notes.db", "wb")
    notes = listbox.get(0, END)
    pickle.dump(notes, f)
    
button1 = Button(textframe, text="Add Item", command = Button1)
button2 = Button(textframe, text="button2")
button3 = Button(textframe, text="button3", command = Button3)

text = Entry(textframe)
text.bind("<Return>", ReturnInsert)

scrollbar = Scrollbar(listframe, orient=VERTICAL)

namebox = Listbox(listframe, yscrollcommand=scrollbar.set)
namebox.bind("<Double-Button-3>", DeleteCurrent)
namebox.bind("<Double-Button-1>", CopyToText)

numbox = Listbox(listframe, yscrollcommand=scrollbar.set)

scrollbar.configure(command=namebox.yview)

text.pack(side=LEFT, fill=X, expand=1)
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
namebox.pack(side=LEFT, fill=BOTH, expand=1)
numbox.pack(side=LEFT, fill=BOTH, expand=1)
scrollbar.pack(side=RIGHT, fill=Y)

textframe.pack(fill=X)
listframe.pack(fill=BOTH, expand=1)

root.geometry("600x400")

try:
    f = file("notes.db", "rb")
    notes = pickle.load(f)
    for item in notes:
        listbox.insert(END, item)
    f.close()
except:
    pass

root.mainloop()

Recommended Answers

All 3 Replies

Python31 includes Tkinter Tile extension ttk. That extension has a Treeview widget that can function as a multicolumn Listbox. Here ia an example, that you may have to simplify somewhat:

"""Demo based on the demo mclist.tcl included with tk source distribution."""

import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkFont

tree_columns = ("country", "capital", "currency")
tree_data = [
    ("Argentina",      "Buenos Aires",     "ARS"),
    ("Australia",      "Canberra",         "AUD"),
    ("Brazil",         "Brazilia",         "BRL"),
    ("Canada",         "Ottawa",           "CAD"),
    ("China",          "Beijing",          "CNY"),
    ("France",         "Paris",            "EUR"),
    ("Germany",        "Berlin",           "EUR"),
    ("India",          "New Delhi",        "INR"),
    ("Italy",          "Rome",             "EUR"),
    ("Japan",          "Tokyo",            "JPY"),
    ("Mexico",         "Mexico City",      "MXN"),
    ("Russia",         "Moscow",           "RUB"),
    ("South Africa",   "Pretoria",         "ZAR"),
    ("United Kingdom", "London",           "GBP"),
    ("United States",  "Washington, D.C.", "USD")
    ]

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

    # reorder data
    data.sort(reverse=descending)
    for indx, item in enumerate(data):
        tree.move(item[1], '', indx)

    # switch the heading so that it will sort in the opposite direction
    tree.heading(col,
        command=lambda col=col: sortby(tree, col, int(not descending)))

class App(object):
    def __init__(self):
        self.tree = None
        self._setup_widgets()
        self._build_tree()

    def _setup_widgets(self):
        msg = ttk.Label(wraplength="4i", justify="left", anchor="n",
            padding=(10, 2, 10, 6),
            text=("Ttk is the new Tk themed widget set. One of the widgets it "
                  "includes is a tree widget, which can be configured to "
                  "display multiple columns of informational data without "
                  "displaying the tree itself. This is a simple way to build "
                  "a listbox that has multiple columns. Clicking on the "
                  "heading for a column will sort the data by that column. "
                  "You can also change the width of the columns by dragging "
                  "the boundary between them."))
        msg.pack(fill='x')

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

        # XXX Sounds like a good support class would be one for constructing
        #     a treeview with scrollbars.
        self.tree = ttk.Treeview(columns=tree_columns, 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 tree_columns:
            self.tree.heading(col, text=col.title(),
                command=lambda c=col: sortby(self.tree, c, 0))
            # XXX tkFont.Font().measure expected args are incorrect according
            #     to the Tk docs
            self.tree.column(col, width=tkFont.Font().measure(col.title()))

        for item in tree_data:
            self.tree.insert('', 'end', values=item)

            # adjust columns lenghts if necessary
            for indx, val in enumerate(item):
                ilen = tkFont.Font().measure(val)
                if self.tree.column(tree_columns[indx], width=None) < ilen:
                    self.tree.column(tree_columns[indx], width=ilen)

def main():
    root = tk.Tk()
    root.wm_title("Multi-Column List")
    root.wm_iconname("mclist")

   # optional?
    import plastik_theme
    plastik_theme.install('~/tile-themes/plastik/plastik')

    app = App()
    root.mainloop()

if __name__ == "__main__":
    main()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.