python Can I duplicate a listbox in two notebook pages
Question:
I’m using python 3.4 and tkinter. I have a notebook with two pages. I have a listbox that needs to be on both pages.
I’m wondering if I can setup the listbox once and use it on both pages, or if I need to setup a separate listbox on each page and manage both as the list box in one page changes?
Answers:
You cannot pack/grid/place the listbox inside two different frames simultaneously.
However, you can re-pack/grid/place the listbox each time the notebook tab changes. To do so, I used the <<NotebookTabChanged>>
event which is triggered each time the notebook tab changes:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.pack()
frame1 = tk.Frame(notebook, bg='red', width=400, height=400)
frame1.pack_propagate(False)
frame2 = tk.Frame(notebook, bg='blue', width=400, height=400)
frame2.pack_propagate(False)
notebook.add(frame1, text='frame 1')
notebook.add(frame2, text='frame 2')
var = tk.StringVar(root, 'a b c d e f g')
listbox = tk.Listbox(notebook, listvariable=var)
def display_listbox(event):
tab = notebook.tabs()[notebook.index('current')]
listbox.pack(in_=tab)
notebook.bind('<<NotebookTabChanged>>', display_listbox)
root.mainloop()
Explanations about display_listbox
:
notebook.tabs()
returns (frame1, frame2)
(i.e the tuple of the tabs)
notebook.index('current')
returns the index of the currently visible tab
- the
in_
option can be used to specify the widget in which we want to pack the listbox (it also works with grid
and place
)
Sharing the same listvariable
between the two list boxes is sufficient to keep them synchronized.
import tkinter as tk
from tkinter import ttk
rootWin = tk.Tk()
rootWin.title('Talk Like A Pirate')
listvar = tk.StringVar()
#create a notebook
pirateBook = ttk.Notebook(rootWin)
#create a tab
tab1 = tk.Frame(pirateBook)
#create a listbox in the tab
listbx1 = tk.Listbox(tab1,
listvariable=listvar,
height=21,
width=56,
selectmode='single'
)
listbx1.pack()
#create another tab
tab2 = tk.Frame(pirateBook)
#create a listbox in the second tab
listbx2 = tk.Listbox(tab2,
listvariable=listvar,
height=21,
width=56,
selectmode='single'
)
listbx2.pack()
#add the tabs to the notebook
pirateBook.add(tab1, text="Tab 1")
pirateBook.add(tab2, text="Tab 2")
#pack the notebook
pirateBook.pack()
#you can access the listbox through the listvariable, but that takes
# a list as the argument so you'll need to build a list first:
ls=list() #or you could just ls = []
#build a list for the list box
ls.append("Arr, matey!")
ls.append("Dead men tell no tales!")
ls.append("Heave ho, me hearties!")
ls.append("I'll cleave ye t'yer brisket a'fore sendin' ye to Davey Jones Locker!")
#then just set the list variable with the list
listvar.set(ls)
#or you can manipulate the data using Listbox()'s data manipulation
# methods, such as .insert()
listbx1.insert(1, "Shiver me timbers!")
listbx2.insert(3, "Yo ho ho!")
listbx1.insert(5, "Ye scurvy dog!")
listbx2.insert('end', "Ye'll be walking the plank, Sharkbait!")
#you'll see this if you run this program from the command line
print(listbx1.get(5))
rootWin.mainloop()
You would do this a little bit differently if you had your tabs in their own classes, making the common variable global, for instance, but the same idea still applies: sharing a common listvariable
.
I’m using python 3.4 and tkinter. I have a notebook with two pages. I have a listbox that needs to be on both pages.
I’m wondering if I can setup the listbox once and use it on both pages, or if I need to setup a separate listbox on each page and manage both as the list box in one page changes?
You cannot pack/grid/place the listbox inside two different frames simultaneously.
However, you can re-pack/grid/place the listbox each time the notebook tab changes. To do so, I used the <<NotebookTabChanged>>
event which is triggered each time the notebook tab changes:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.pack()
frame1 = tk.Frame(notebook, bg='red', width=400, height=400)
frame1.pack_propagate(False)
frame2 = tk.Frame(notebook, bg='blue', width=400, height=400)
frame2.pack_propagate(False)
notebook.add(frame1, text='frame 1')
notebook.add(frame2, text='frame 2')
var = tk.StringVar(root, 'a b c d e f g')
listbox = tk.Listbox(notebook, listvariable=var)
def display_listbox(event):
tab = notebook.tabs()[notebook.index('current')]
listbox.pack(in_=tab)
notebook.bind('<<NotebookTabChanged>>', display_listbox)
root.mainloop()
Explanations about display_listbox
:
notebook.tabs()
returns(frame1, frame2)
(i.e the tuple of the tabs)notebook.index('current')
returns the index of the currently visible tab- the
in_
option can be used to specify the widget in which we want to pack the listbox (it also works withgrid
andplace
)
Sharing the same listvariable
between the two list boxes is sufficient to keep them synchronized.
import tkinter as tk
from tkinter import ttk
rootWin = tk.Tk()
rootWin.title('Talk Like A Pirate')
listvar = tk.StringVar()
#create a notebook
pirateBook = ttk.Notebook(rootWin)
#create a tab
tab1 = tk.Frame(pirateBook)
#create a listbox in the tab
listbx1 = tk.Listbox(tab1,
listvariable=listvar,
height=21,
width=56,
selectmode='single'
)
listbx1.pack()
#create another tab
tab2 = tk.Frame(pirateBook)
#create a listbox in the second tab
listbx2 = tk.Listbox(tab2,
listvariable=listvar,
height=21,
width=56,
selectmode='single'
)
listbx2.pack()
#add the tabs to the notebook
pirateBook.add(tab1, text="Tab 1")
pirateBook.add(tab2, text="Tab 2")
#pack the notebook
pirateBook.pack()
#you can access the listbox through the listvariable, but that takes
# a list as the argument so you'll need to build a list first:
ls=list() #or you could just ls = []
#build a list for the list box
ls.append("Arr, matey!")
ls.append("Dead men tell no tales!")
ls.append("Heave ho, me hearties!")
ls.append("I'll cleave ye t'yer brisket a'fore sendin' ye to Davey Jones Locker!")
#then just set the list variable with the list
listvar.set(ls)
#or you can manipulate the data using Listbox()'s data manipulation
# methods, such as .insert()
listbx1.insert(1, "Shiver me timbers!")
listbx2.insert(3, "Yo ho ho!")
listbx1.insert(5, "Ye scurvy dog!")
listbx2.insert('end', "Ye'll be walking the plank, Sharkbait!")
#you'll see this if you run this program from the command line
print(listbx1.get(5))
rootWin.mainloop()
You would do this a little bit differently if you had your tabs in their own classes, making the common variable global, for instance, but the same idea still applies: sharing a common listvariable
.