I’m trying to code a small Setup-App with multiple frames where buttons on the bottom part let you go back and forth. Problem is
- The
current_frame
value is increased at the beginning of the code through theframe_next
function although it should be called only when I press the “Nächste” (“next”) button - I can’t get the “Zurück” (“back”) button to work for similar reasons.
I know this topic has been discussed already (Why is my Button’s command executed immediately when I create the Button, and not when I click it?) but their solutions where lambda commands or the bind function which both somehow didn’t work for me…
My Code:
# =============================== imports
import tkinter as tk
from tkinter import ttk
# =============================== variables
current_frame = 0
# =============================== functions
def frame_next(x, window):
global current_frame
print("frame:%s, x:%x" %(current_frame, x))
if x == len(frames_arr):
window.destroy()
else:
current_frame = current_frame+1
frame = frames_arr[x]
frame.tkraise()
print("frame:%s, x:%x" %(current_frame, x))
def frame_back(x, window):
global current_frame
print("frame:%s, x:%x" %(current_frame, x))
if x == 1:
window.destroy()
else:
current_frame = current_frame-1
# x = x - 1
frame = frames_arr[x]
frame.tkraise()
print("frame:%s, x:%x" %(current_frame, x))
# =============================== main code
# window handling
window = tk.Tk()
window.geometry('400x500')
window.resizable(False, False)
window.rowconfigure(0, weight=1)
window.columnconfigure(0, weight=1)
# initialize frames
f1 = tk.Frame(window)
f2 = tk.Frame(window)
f3 = tk.Frame(window)
frames_arr = [f1, f2, f3]
for frame in (f1, f2, f3):
frame.grid(row=0,column=0,sticky='nsew')
# ================================ BIND SOLUTION ================================
# btn_back = tk.Button(nav, text='Zurück')
# btn_back.pack(side="left")
# btn_back.bind("<ButtonBack>", frame_back(current_frame, window))
# btn_next = tk.Button(nav, text='Nächste')
# btn_next.pack(side="right")
# btn_next.bind("<ButtonNext>", frame_next(current_frame, window))
# ================================ LAMBDA SOLUTION ==============================
nav = tk.Frame(window)
nav.grid(row=1,column=0,sticky='nsew', pady=10, padx=10)
btn_back = tk.Button(nav, text='Zurück', command=lambda:frame_back(current_frame, window)).pack(side="left")
btn_next = tk.Button(nav, text='Nächste', command=lambda:frame_next(current_frame, window)).pack(side="right")
# window content
# frame 1
f1_title = tk.Label(f1, text='Page 1').pack()
f1_txt_opcserver = tk.Label(f1, text='OPC UA Serveradresse:').pack()
f1_in_opcserver = ttk.Entry(f1).pack(fill='both', ipady=10, padx=10, pady=10)
f1_txt_testcon = tk.Label(f1).pack()
f1_btn_testcon = tk.Button(f1, text='Verbindung prüfen.').pack() # , command=lambda:connect_server(f1_in_opcserver, f1_txt_testcon)
# frame 2
f2_title = tk.Label(f2, text='Page 2').pack(fill='both')
f2_txt_connection = tk.Label(f2).pack(fill='both')
f2_txt_usecase = tk.Label(f2, text='Select an use case.').pack(fill='both')
f2_cbb_usecase = ttk.Combobox(f2, values=usecases, state='readonly') # .pack(fill='both', padx= 200)
f2_cbb_usecase.pack() # muss irgendwie in extrazeile stehen ... kA wieso
f2_cbb_usecase.bind("<<ComboboxSelected>>") # , show_variables) # sollte denke ich auch mit command = in ttk.Combobox funktionieren
f2_list_variables = tk.Listbox(f2).pack(expand=True, fill='both', padx= 200)
f2_btn_next = tk.Button(f2, text='Next', command=lambda:frame_next(f3)).pack(fill='x', ipady=15, side=tk.BOTTOM)
# frame 3
f3_title = tk.Label(f3, text='Page 3').pack(fill='both')
f3_btn_next = tk.Button(f3, text='Finish', command=window.destroy).pack(fill='x', ipady=15, side=tk.BOTTOM)
# display first time and loop
frame_next(current_frame, window)
window.mainloop()