0

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.

how to transfer the numbers in a textfile to the next page by importing that textfile in page one using tkinter?

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?

Luke20
  • 23
  • 5

1 Answers1

0

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.

acw1668
  • 40,144
  • 5
  • 22
  • 34
  • Thanks for the reply. just a question. It seems the variable gets its value from `Label_5` in PageTwo and not the variable in PageOne. because when I deleted `self.label_5 = tk.Label(self.frame2, textvariable=self.data.Tot_grids) self.label_5.pack()`, the code doesnt work. so, how we can dirrectly relates that to PageOne calss? – Luke20 Feb 16 '22 at 17:14
  • @Luke20 What do you mean by "the code doesnt work" after deleting `self.label_5`? I still get the correct result in `self.label_6`. – acw1668 Feb 17 '22 at 09:39
  • you are right. it was my mistake. May I ask what should I do when the variable passing from PageOne to PageTwo is a list of numbers? because there is no variable to define that. and StringVar, and IntVar or DoubleVar cannot do that? – Luke20 Feb 17 '22 at 16:42
  • Try using `Variable`. – acw1668 Feb 17 '22 at 16:45
  • Sorry, didn't quite understand. what is `Variable`? could you please let me know what should I exactly look for on the net? – Luke20 Feb 17 '22 at 16:50
  • `Variable` is the base class of `StringVar`, `IntVar`, etc. – acw1668 Feb 18 '22 at 00:34