I have a gui with two tabs and would like to switch back and forth between the tabs while keeping the content of the tabs. If I do this all in one function, then it works fine, but since I have more in the individual functions. I have outsourced them. Now I have bound the individual functions to the tabs. But here I have the problem that I overwrite the tabs with every change. But I would like to switch between the tabs without overwriting the entries. I understand why I overwrite the input. After all, I call the individual functions with rountine
and overwrite them that way. Unfortunately I do not know how to do it better.
import tkinter as tk
from tkinter import ttk
class display():
def __init__(self):
self.root = tk.Tk()
self.root.geometry('400x300')
self.root.title('Notebook Demo')
def gui(self):
# create a notebook
self.notebook = ttk.Notebook(self.root)
self.notebook.place(rely=0.0, relheight=1, relwidth=1)
# create frames
self.frame1 = ttk.Frame(self.notebook, width=400, height=280)
self.frame2 = ttk.Frame(self.notebook, width=400, height=280)
self.frame1.place(rely=0.0, relheight=1, relwidth=1)
self.frame2.place(rely=0.0, relheight=1, relwidth=1)
# add frames to notebook
self.notebook.add(self.frame1, text='General Information')
self.notebook.add(self.frame2, text='Profile')
self.notebook.bind("<<NotebookTabChanged>>", self.routine)
self.gu1()
self.root.update_idletasks()
self.root.mainloop()
def routine(self,event):
if self.notebook.index("current") == 1:
self.gu1()
else:
self.gu2()
def gu1(self):
button1 = tk.Button(self.frame1, text="test1", command=self.changeText)
button1.grid(column=0, row=0)
self.label1 = tk.Label(self.frame1, text="test1")
self.label1.grid(column=1, row=0)
self.root.mainloop()
def gu2(self):
button2 = tk.Button(self.frame2, text="test2", command=self.changeText2)
button2.grid(column=0, row=0)
self.label2 = tk.Label(self.frame2, text="test2")
self.label2.grid(column=1, row=0)
self.root.mainloop()
def changeText(self):
self.label1["text"] = "change1"
def changeText2(self):
self.label2["text"] = "change2"
if __name__ == "__main__":
display().gui()
CodePudding user response:
All problem is that you use .gu1()
and .gu2()
in routine()
.
You should run .gu1()
and .gu2()
only once - at start in gui()
.
def gui(self):
# ... code ...
self.notebook.bind("<<NotebookTabChanged>>", self.routine)
self.gu1() # create at start
self.gu2() # create at start
def routine(self,event):
if self.notebook.index("current") == 1:
#self.gu1() # DON'T DO THIS
print('selected tab 1')
else:
#self.gu2() # DON'T DO THIS
print('selected tab 2')
Working code:
tkinter
should use only one mainloop()
import tkinter as tk
from tkinter import ttk
class display():
def __init__(self):
self.root = tk.Tk()
self.root.geometry('400x300')
self.root.title('Notebook Demo')
def gui(self):
# create a notebook
self.notebook = ttk.Notebook(self.root)
self.notebook.place(rely=0.0, relheight=1, relwidth=1)
# create frames
self.frame1 = ttk.Frame(self.notebook, width=400, height=280)
self.frame2 = ttk.Frame(self.notebook, width=400, height=280)
self.frame1.place(rely=0.0, relheight=1, relwidth=1)
self.frame2.place(rely=0.0, relheight=1, relwidth=1)
# add frames to notebook
self.notebook.add(self.frame1, text='General Information')
self.notebook.add(self.frame2, text='Profile')
self.notebook.bind("<<NotebookTabChanged>>", self.routine)
self.gu1()
self.gu2()
self.root.update_idletasks()
self.root.mainloop()
def routine(self,event):
if self.notebook.index("current") == 1:
#self.gu1() # DON'T DO THIS
print('selected tab 1')
else:
#self.gu2() # DON'T DO THIS
print('selected tab 2')
def gu1(self):
button1 = tk.Button(self.frame1, text="test1", command=self.changeText)
button1.grid(column=0, row=0)
self.label1 = tk.Label(self.frame1, text="test1")
self.label1.grid(column=1, row=0)
def gu2(self):
button2 = tk.Button(self.frame2, text="test2", command=self.changeText2)
button2.grid(column=0, row=0)
self.label2 = tk.Label(self.frame2, text="test2")
self.label2.grid(column=1, row=0)
def changeText(self):
self.label1["text"] = "change1"
def changeText2(self):
self.label2["text"] = "change2"
if __name__ == "__main__":
display().gui()
EDIT:
If you have to create some widgets in tabs with delays (ie. to wait for user's values in other widgets) then you should use boolean variables (True/False) to run it only once in routine()
def gui(self):
# ... code ...
self.gu1_created = False
self.gu2_created = False
self.notebook.bind("<<NotebookTabChanged>>", self.routine)
def routine(self,event):
if self.notebook.index("current") == 1:
if not self.gu1_created:
self.gu1()
self.gu1_created = True
print('selected tab 1')
else:
if not self.gu2_created:
self.gu2()
self.gu2_created = True
print('selected tab 2')