My app displays details for one person at a time based on a current_person_id
and other information related to that person which is stored in a database. I wanted to change the details displayed based on the order in which different persons' details had been seen, so it would work like a browser's back/forward button.
I found instructions here, here, and here which suggested using two stacks, one for the back button and one for the forward button. I didn't understand these instructions so I compared them with each other and compiled a more succinct and better organized set of instructions.
It took several hours but I finally managed to get this to work in Tkinter. I will answer my question below.
The back stack and forward stack start out empty.
On navigate to new page not using back/forward
On click back
On click forward
In a class the global variables can be changed to instance variables.
import tkinter as tk
bck_stack = []
fwd_stack = []
current_person_id = 1
def change_current_person(key):
""" Append current_person_id to forward or backward stack before changing
it to its new value. The current_person_id is not in either stack.
"""
global fwd_stack, current_person_id
if key == "changer":
got = ent.get()
if len(got) == 0:
return
fwd_stack = []
bck_stack.append(current_person_id)
current_person_id = got
redraw(current_person_id)
ent.delete(0, "end")
elif key == "back":
if len(bck_stack) == 0:
pass
else:
fwd_stack.append(current_person_id)
current_person_id = bck_stack.pop()
redraw(current_person_id)
elif key == "forward":
if len(fwd_stack) == 0:
pass
else:
bck_stack.append(current_person_id)
current_person_id = fwd_stack.pop()
redraw(current_person_id)
def redraw(current_person_id):
current["text"] = current_person_id
bck_history.delete("1.0", "end")
bck_history.insert("1.0", bck_stack)
fwd_history.delete("1.0", "end")
fwd_history.insert("1.0", fwd_stack)
if __name__ == "__main__":
buttons = {}
root = tk.Tk()
root.geometry("+700+300")
root.config(bg="black")
lab_bck = tk.Label(
root, text="Back Stack", anchor="w", bg="black", fg="white")
bck_history = tk.Text(
root, width=40, height=4, bg="steelblue", fg="white")
bck_history.insert("1.0", "Back history displays here.")
lab_fwd = tk.Label(
root, text="Forward Stack", anchor="w", bg="black", fg="white")
fwd_history = tk.Text(
root, width=40, height=4, bg="steelblue", fg="white")
fwd_history.insert("1.0", "Forward history displays here.")
ent = tk.Entry(root, bg="steelblue", fg="white")
for key in ("changer", "back", "forward"):
buttons[key] = tk.Button(
root, bg="teal", command=lambda key=key: change_current_person(key))
current = tk.Label(
root, width=5, height=1, bg="blue", fg="white",
font=("arial black", 21), text=current_person_id)
buttons["changer"]["text"] = "CHANGE CURRENT PERSON"
buttons["back"]["text"] = "BACK"
buttons["forward"]["text"] = "FORWARD"
lab_bck.grid(column=0, row=0)
bck_history.grid(column=0, row=1, columnspan=3)
lab_fwd.grid(column=0, row=2)
fwd_history.grid(column=0, row=3, columnspan=3)
ent.grid(column=0, row=4)
buttons["changer"].grid(column=1, row=4)
current.grid(column=2, row=4)
buttons["back"].grid(column=0, row=5)
buttons["forward"].grid(column=1, row=5)
ent.focus_set()
root.mainloop()