I wanted to create an app to calculate the total number of grids, by getting the number of grids in X,Y, and Z directions. I also want to use the result to be moved in the next windows. I found this post below, and I used it as my code basis.
I could write my code to calculate the total grids and show it in the next window.
import tkinter as tk
class Data:
def __init__(self):
self.nx = tk.IntVar()
self.ny = tk.IntVar()
self.nz = tk.IntVar()
self.Tot_grids = tk.IntVar()
self.A = tk.IntVar()
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Test app")
self.geometry("400x400")
container = tk.Frame(self)
container.pack()
self.data = Data()
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self.data)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.frames[PageOne].button4_P1.config(command=self.go_to_page_two)
self.show_frame(PageOne)
def go_to_page_two(self):
self.show_frame(PageTwo)
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
self.frame_1 = tk.Frame(self)
self.frame_1.grid(row=0, column=0)
self.label_1 = tk.Label(self.frame_1, text="nx")
self.label_1.grid(row=0, column=0)
self.entry_1 = tk.Entry(self.frame_1, textvariable=data.nx)
self.entry_1.grid(row=0, column=1)
self.label_2 = tk.Label(self.frame_1, text="ny")
self.label_2.grid(row=1, column=0)
self.entry_2 = tk.Entry(self.frame_1, textvariable=data.ny)
self.entry_2.grid(row=1, column=1)
self.label_3 = tk.Label(self.frame_1, text="nz")
self.label_3.grid(row=2, column=0)
self.entry_3 = tk.Entry(self.frame_1, textvariable=data.nz)
self.entry_3.grid(row=2, column=1)
def total_grids():
nt = data.nx.get() * data.ny.get() * data.nz.get()
self.label_4.config(text=str(nt))
data.Tot_grids.set(nt)
self.button1 = tk.Button(self.frame_1, text="Calculate", command=total_grids)
self.button1.grid(row=3, column=0, columnspan=2)
self.button4_P1 = tk.Button(self.frame_1, text="Continue")
self.button4_P1.grid(row=5, column=0, columnspan=4, pady=5)
self.label_4 = tk.Label(self.frame_1)
self.label_4.grid(row=4, column=0, columnspan=2)
class PageTwo(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
self.frame2 = tk.Frame(self)
self.frame2.pack()
self.label_5 = tk.Label(self.frame2, textvariable=self.data.Tot_grids)
self.label_5.pack()
app = SampleApp()
app.mainloop()
But, I don't know how to use it for further calculations. assume I want to do a simple calculation and add the passed variable by 100
. I added a few lines to do that in class PageTwo
, but it gives me an error.
import tkinter as tk
class Data:
def __init__(self):
self.nx = tk.IntVar()
self.ny = tk.IntVar()
self.nz = tk.IntVar()
self.Tot_grids = tk.IntVar()
self.A = tk.IntVar()
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Test app")
self.geometry("400x400")
container = tk.Frame(self)
container.pack()
self.data = Data()
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self.data)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.frames[PageOne].button4_P1.config(command=self.go_to_page_two)
self.show_frame(PageOne)
def go_to_page_two(self):
self.show_frame(PageTwo)
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
self.frame_1 = tk.Frame(self)
self.frame_1.grid(row=0, column=0)
self.label_1 = tk.Label(self.frame_1, text="nx")
self.label_1.grid(row=0, column=0)
self.entry_1 = tk.Entry(self.frame_1, textvariable=data.nx)
self.entry_1.grid(row=0, column=1)
self.label_2 = tk.Label(self.frame_1, text="ny")
self.label_2.grid(row=1, column=0)
self.entry_2 = tk.Entry(self.frame_1, textvariable=data.ny)
self.entry_2.grid(row=1, column=1)
self.label_3 = tk.Label(self.frame_1, text="nz")
self.label_3.grid(row=2, column=0)
self.entry_3 = tk.Entry(self.frame_1, textvariable=data.nz)
self.entry_3.grid(row=2, column=1)
def total_grids():
nt = data.nx.get() * data.ny.get() * data.nz.get()
self.label_4.config(text=str(nt))
data.Tot_grids.set(nt)
self.button1 = tk.Button(self.frame_1, text="Calculate", command=total_grids)
self.button1.grid(row=3, column=0, columnspan=2)
self.button4_P1 = tk.Button(self.frame_1, text="Continue")
self.button4_P1.grid(row=5, column=0, columnspan=4, pady=5)
self.label_4 = tk.Label(self.frame_1)
self.label_4.grid(row=4, column=0, columnspan=2)
class PageTwo(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
self.frame2 = tk.Frame(self)
self.frame2.pack()
self.label_5 = tk.Label(self.frame2, textvariable=self.data.Tot_grids)
self.label_5.pack()
self.data.A = self.data.Tot_grids 100
self.label_6 = tk.Label(self.frame2, textvariable=self.data.A)
self.label_6.pack()
app = SampleApp()
app.mainloop()
I also have this question, do we really need to use self
before every label, entry fields, or button. I removed some of them, and the code was working for my code. Does removing them cause problems later?
CodePudding user response:
You can us tkinter variable .trace()
to update Data.A
whenever Data.tot_grids
is updated:
class PageTwo(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
self.frame2 = tk.Frame(self)
self.frame2.pack()
self.label_5 = tk.Label(self.frame2, textvariable=self.data.Tot_grids)
self.label_5.pack()
self.label_6 = tk.Label(self.frame2, textvariable=self.data.A)
self.label_6.pack()
# call on_grids_updated() whenever Data.Tot_grids is updated
self.data.Tot_grids.trace_add('write', self.on_grids_updated)
def on_grids_updated(self, *args):
self.data.A.set(self.data.Tot_grids.get() 100)
For question on using self
, if the variable will be accessed in other class methods, then you need to prefix it with self.
to make it an instance variable, otherwise the prefix is not necessary.