Python Forum
how to add two numbers and pass the result to the next page in tkinter?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how to add two numbers and pass the result to the next page in tkinter?
#1
I am new to tkinter. I want to add two numbers and pass the result to the second page. in my code, I don't understand why instead of adding the numbers, it attaches them and shows them on the second page. I have introduced them as integers, but it still recognizes them as strings.

import tkinter as tk
from tkinter import *

Title_Font = ("Helvetica", 16, "bold")
Label_Font = ("Helvetica", 10)


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        self.title("Summation App")
        container.pack()

        self.frames = {}
        for F in (PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
            self.geometry("400x400")

        self.show_frame(PageOne)

    def show_frame(self, c):
        frame = self.frames[c]
        frame.tkraise()


class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        self.frame1 = tk.LabelFrame(self, text="This is page one", font=Title_Font)
        self.frame1.pack(padx=10, pady=10)

        label1 = tk.Label(self.frame1, text= "First No.", font = Label_Font)
        label1.grid(row=0, column=0)

        label2 = tk.Label(self.frame1, text= "Second No.", font = Label_Font)
        label2.grid(row=1, column=0)

        first_no = IntVar()
        second_no = IntVar()

        self.entry1 = tk.Entry(self.frame1, textvariable=first_no)
        self.entry1.grid(row=0, column=1)

        self.entry2 = tk.Entry(self.frame1, textvariable=second_no)
        self.entry2.grid(row=1, column=1)

        button1 = tk.Button(self.frame1, text="Go to Page Two", command=lambda: self.go_to_page_two(), font=Label_Font)
        button1.grid(row=4, column=0, padx=10, pady=10)

    def go_to_page_two(self):
        self.controller.SomeVar = self.entry1.get() + self.entry2.get()
        print(self.controller.SomeVar)
        self.controller.frames[PageTwo].correct_label()
        self.controller.show_frame(PageTwo)


class PageTwo(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        self.frame2 = tk.LabelFrame(self, text="This is page two", font=Title_Font)
        self.frame2.pack()

        self.label3 = tk.Label(self.frame2)
        self.label3.pack()

    def correct_label(self):
        self.label3.config(text=self.controller.SomeVar)


app = SampleApp()
app.mainloop()
BashBedlam likes this post
Reply
#2
Try changing line 56 to:
        self.controller.SomeVar = int (self.entry1.get()) + int (self.entry2.get())
Here's the whole thing.
import tkinter as tk
from tkinter import *
 
Title_Font = ("Helvetica", 16, "bold")
Label_Font = ("Helvetica", 10)
 
 
class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        self.title("Summation App")
        container.pack()
 
        self.frames = {}
        for F in (PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
            self.geometry("400x400")
 
        self.show_frame(PageOne)
 
    def show_frame(self, c):
        frame = self.frames[c]
        frame.tkraise()
 
 
class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
 
        self.frame1 = tk.LabelFrame(self, text="This is page one", font=Title_Font)
        self.frame1.pack(padx=10, pady=10)
 
        label1 = tk.Label(self.frame1, text= "First No.", font = Label_Font)
        label1.grid(row=0, column=0)
 
        label2 = tk.Label(self.frame1, text= "Second No.", font = Label_Font)
        label2.grid(row=1, column=0)
 
        first_no = IntVar()
        second_no = IntVar()
 
        self.entry1 = tk.Entry(self.frame1, textvariable=first_no)
        self.entry1.grid(row=0, column=1)
 
        self.entry2 = tk.Entry(self.frame1, textvariable=second_no)
        self.entry2.grid(row=1, column=1)
 
        button1 = tk.Button(self.frame1, text="Go to Page Two", command=lambda: self.go_to_page_two(), font=Label_Font)
        button1.grid(row=4, column=0, padx=10, pady=10)
 
    def go_to_page_two(self):
        self.controller.SomeVar = int (self.entry1.get()) + int (self.entry2.get())
        print(self.controller.SomeVar)
        self.controller.frames[PageTwo].correct_label()
        self.controller.show_frame(PageTwo)
 
 
class PageTwo(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
 
        self.frame2 = tk.LabelFrame(self, text="This is page two", font=Title_Font)
        self.frame2.pack()
 
        self.label3 = tk.Label(self.frame2)
        self.label3.pack()
 
    def correct_label(self):
        self.label3.config(text=self.controller.SomeVar)
 
 
app = SampleApp()
app.mainloop()
menator01 and pymn like this post

Attached Files

Thumbnail(s)
   
Reply
#3
Oh, thank you so much.
Reply
#4
You don't need a lambda expression for something like this:
command=lambda: self.go_to_page_two()
Instead use:
command=self.go_go_page_two
Only use a lambda if you want to specify arguments for the method call.

In this code you are creating a string by concatenating the strings in entry1 and entry2.
self.controller.SomeVar = self.entry1.get() + self.entry2.get()
I do not like Page1 having to know about things in Page2. For something small like this it is ok, but if you had several windows that share information, this way of keeping everything current quickly becomes unmaintainable. A better design splits out all the information you are working with into it's own entity. Frame 1 would change a value in this data entity. If Frame 2 has a display for that data, registers a function to call when the value of the data changes.
import tkinter as tk

class Data:
    """I an a data entity shared by the forms"""
    def __init__(self):
        self.first_no = tk.IntVar()
        self.second_no = tk.IntVar()
        self.someVar = tk.IntVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title("Summation App")
        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")
  
        # I knob about all the frames, so it is ok for me to reference parts of their API
        self.frames[PageOne].page_button.config(command=self.go_to_page_two)
        self.show_frame(PageOne)

    def go_to_page_two(self):
        # I do not update the the label.  There are limits
        self.data.someVar.set(self.data.first_no.get() + self.data.second_no.get())
        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.frame1 = tk.LabelFrame(self, text="This is page one")
        self.frame1.pack(padx=10, pady=10)
  
        label1 = tk.Label(self.frame1, text= "First No.")
        label1.grid(row=0, column=0)
  
        label2 = tk.Label(self.frame1, text= "Second No.")
        label2.grid(row=1, column=0)
  
        self.entry1 = tk.Entry(self.frame1, textvariable=data.first_no)
        self.entry1.grid(row=0, column=1)
  
        self.entry2 = tk.Entry(self.frame1, textvariable=data.second_no)
        self.entry2.grid(row=1, column=1)
  
        self.page_button = tk.Button(self.frame1, text="Go to Page Two")
        self.page_button.grid(row=4, column=0, padx=10, pady=10)
  
  
class PageTwo(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data
  
        self.frame2 = tk.LabelFrame(self, text="This is page two")
        self.frame2.pack()
  
        self.label3 = tk.Label(self.frame2)
        self.label3.pack()

        # When someone changes someVar I need to update the label
        data.someVar.trace('w', lambda a, b, c: self.correct_label())
  
    def correct_label(self):
        self.label3.config(text=self.data.someVar.get())
  
  
app = SampleApp()
app.mainloop()
pymn likes this post
Reply
#5
(Feb-14-2022, 05:37 AM)deanhystad Wrote: You don't need a lambda expression for something like this:
command=lambda: self.go_to_page_two()
Instead use:
command=self.go_go_page_two
Only use a lambda if you want to specify arguments for the method call.

In this code you are creating a string by concatenating the strings in entry1 and entry2.
self.controller.SomeVar = self.entry1.get() + self.entry2.get()
I do not like Page1 having to know about things in Page2. For something small like this it is ok, but if you had several windows that share information, this way of keeping everything current quickly becomes unmaintainable. A better design splits out all the information you are working with into it's own entity. Frame 1 would change a value in this data entity. If Frame 2 has a display for that data, registers a function to call when the value of the data changes.
import tkinter as tk

class Data:
    """I an a data entity shared by the forms"""
    def __init__(self):
        self.first_no = tk.IntVar()
        self.second_no = tk.IntVar()
        self.someVar = tk.IntVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title("Summation App")
        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")
  
        # I knob about all the frames, so it is ok for me to reference parts of their API
        self.frames[PageOne].page_button.config(command=self.go_to_page_two)
        self.show_frame(PageOne)

    def go_to_page_two(self):
        # I do not update the the label.  There are limits
        self.data.someVar.set(self.data.first_no.get() + self.data.second_no.get())
        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.frame1 = tk.LabelFrame(self, text="This is page one")
        self.frame1.pack(padx=10, pady=10)
  
        label1 = tk.Label(self.frame1, text= "First No.")
        label1.grid(row=0, column=0)
  
        label2 = tk.Label(self.frame1, text= "Second No.")
        label2.grid(row=1, column=0)
  
        self.entry1 = tk.Entry(self.frame1, textvariable=data.first_no)
        self.entry1.grid(row=0, column=1)
  
        self.entry2 = tk.Entry(self.frame1, textvariable=data.second_no)
        self.entry2.grid(row=1, column=1)
  
        self.page_button = tk.Button(self.frame1, text="Go to Page Two")
        self.page_button.grid(row=4, column=0, padx=10, pady=10)
  
  
class PageTwo(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data
  
        self.frame2 = tk.LabelFrame(self, text="This is page two")
        self.frame2.pack()
  
        self.label3 = tk.Label(self.frame2)
        self.label3.pack()

        # When someone changes someVar I need to update the label
        data.someVar.trace('w', lambda a, b, c: self.correct_label())
  
    def correct_label(self):
        self.label3.config(text=self.data.someVar.get())
  
  
app = SampleApp()
app.mainloop()

Thank you very much. this method was perfect. I wondered to know if I had a function in my page one then how should I pass that to the next page. For example in this code I have added a function to open a text file and read that, and I want to pass those lines to the next page

import tkinter as tk
from tkinter import filedialog

class Data:

    def __init__(self):
        self.first_no = tk.IntVar()
        self.second_no = tk.IntVar()
        self.summ = tk.IntVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title("Summation App")
        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].page_button.config(command=self.go_to_page_two)
        self.show_frame(PageOne)

    def go_to_page_two(self):
        self.data.summ.set(self.data.first_no.get() + self.data.second_no.get())
        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

        frame1 = tk.LabelFrame(self, text="This is page one")
        frame1.pack(padx=10, pady=10)

        label1 = tk.Label(frame1, text="First No.")
        label1.grid(row=0, column=0)

        label2 = tk.Label(frame1, text="Second No.")
        label2.grid(row=1, column=0)

        self.entry1 = tk.Entry(frame1, textvariable=data.first_no)
        self.entry1.grid(row=0, column=1)

        self.entry2 = tk.Entry(frame1, textvariable=data.second_no)
        self.entry2.grid(row=1, column=1)

        self.page_button = tk.Button(frame1, text="Go to Page Two")
        self.page_button.grid(row=3, column=0, padx=10, pady=10)

        label_1 = tk.Label(frame1, text="Import the file")
        label_1.grid(row=2, column=0, padx=10)

        def opentext():
            my_file = filedialog.askopenfilenames(initialdir="/pycharm", title="Select your file")
            with open(my_file, 'r') as infile1:
                lines = infile1.read()
                

        button1 = tk.Button(frame1, text="Open file(s)", command=opentext)
        button1.grid(row=2, column=1, padx=10, pady=10)

class PageTwo(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data

        self.frame2 = tk.LabelFrame(self, text="This is page two")
        self.frame2.pack()

        self.label3 = tk.Label(self.frame2)
        self.label3.pack()

        # When someone changes summ, I need to update the label
        data.summ.trace('w', lambda a, b, c: self.correct_label())

    def correct_label(self):
        self.label3.config(text=self.data.summ.get())


app = SampleApp()
app.mainloop()
and in the textfile also there are a couple of numbers such as 1 2 3 4 5
Reply
#6
It is not good user interface design to have controls in one "page" change displays in a second "page". It is not an absolute, but should give you pause. If you don't immediately see the results of your actions, how do you know that you performed the action correctly? For your example I would put a button in frame 2 that draws a dialog to enter values for first_no and second_no which are applied when you press the "Ok" button in the dialog, or ignored if you press the "Cancel" button.

I cannot tell you what is a good design for your application (I don't know what you are trying to achieve), but I can say you should be spending most of your programming time thinking about the user experience and relatively little time writing code.
Reply
#7
(Feb-14-2022, 08:17 PM)deanhystad Wrote: It is not good user interface design to have controls in one "page" change displays in a second "page". It is not an absolute, but should give you pause. If you don't immediately see the results of your actions, how do you know that you performed the action correctly? For your example I would put a button in frame 2 that draws a dialog to enter values for first_no and second_no which are applied when you press the "Ok" button in the dialog, or ignored if you press the "Cancel" button.

I cannot tell you what is a good design for your application (I don't know what you are trying to achieve), but I can say you should be spending most of your programming time thinking about the user experience and relatively little time writing code.

You are right. I am a little new to tkinter. with this code for summation and the one I just said to open a textfile, I am trying to learn.
I want to make an app to get variables (from entry boxes, or from importing a file), and pass these variables through pages. This was an easy example I just created to learn the basics and then move to the harder cases.
Thank you
Reply
#8
(Feb-14-2022, 08:17 PM)deanhystad Wrote: It is not good user interface design to have controls in one "page" change displays in a second "page". It is not an absolute, but should give you pause. If you don't immediately see the results of your actions, how do you know that you performed the action correctly? For your example I would put a button in frame 2 that draws a dialog to enter values for first_no and second_no which are applied when you press the "Ok" button in the dialog, or ignored if you press the "Cancel" button.

I cannot tell you what is a good design for your application (I don't know what you are trying to achieve), but I can say you should be spending most of your programming time thinking about the user experience and relatively little time writing code.

I am still working on this problem. I am so confused. could you please help me with that. imagine I have a text file with a few numbers in that, and I want to pass it as a string to the next page. I updated my code. I created a new attribute in Data class as a string (new_Var). I cannot figure out how to make the connection between my opentext() function and the new_Var.

import tkinter as tk
from tkinter import filedialog

class Data:

    def __init__(self):
        self.first_no = tk.IntVar()
        self.second_no = tk.IntVar()
        self.summ = tk.IntVar()
        self.new_Var = tk.StringVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title("Summation App")
        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].page_button.config(command=self.go_to_page_two)
        self.show_frame(PageOne)

    def go_to_page_two(self):
        self.data.summ.set(self.data.first_no.get() + self.data.second_no.get())
        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

        frame1 = tk.LabelFrame(self, text="This is page one")
        frame1.pack(padx=10, pady=10)

        label1 = tk.Label(frame1, text="First No.")
        label1.grid(row=0, column=0)

        label2 = tk.Label(frame1, text="Second No.")
        label2.grid(row=1, column=0)

        self.entry1 = tk.Entry(frame1, textvariable=data.first_no)
        self.entry1.grid(row=0, column=1)

        self.entry2 = tk.Entry(frame1, textvariable=data.second_no)
        self.entry2.grid(row=1, column=1)

        self.page_button = tk.Button(frame1, text="Go to Page Two")
        self.page_button.grid(row=3, column=0, padx=10, pady=10)

        label3 = tk.Label(frame1, text="Import the file")
        label3.grid(row=2, column=0, padx=10)

        def opentext():
            my_file = filedialog.askopenfilenames(initialdir="/pycharm", title="Select your file")
            for T in my_file:
                with open(T, 'r') as infile1:
                    lines = infile1.read()
                    label4.config(text=lines)
                    return lines

        self.button1 = tk.Button(frame1, text="Open file(s)", command=opentext)
        self.button1.grid(row=2, column=1, padx=10, pady=10)

        label4 = tk.Label(frame1)
        label4.grid(row=3, column=1)

class PageTwo(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data

        self.frame2 = tk.LabelFrame(self, text="This is page two")
        self.frame2.pack()

        self.label5 = tk.Label(self.frame2)
        self.label5.pack()

        self.label6 = tk.Label(self.frame2)
        self.label6.pack()

        # When someone changes summ, I need to update the label
        data.summ.trace('w', lambda a, b, c: self.correct_label())

    def correct_label(self):
        self.label5.config(text=self.data.summ.get())
        self.label6.config(text=self.data.new_Var)


app = SampleApp()
app.mainloop()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pass a variable between tkinter and toplevel windows janeik 10 2,140 Jan-24-2024, 06:44 AM
Last Post: Liliana
  [Tkinter] How to get the result of a ping to show in tkinter? jacklee26 6 7,723 Feb-10-2023, 01:12 PM
Last Post: NebularNerd
  [Tkinter] tkinter best way to pass parameters to a function Pedroski55 3 4,737 Nov-17-2021, 03:21 AM
Last Post: deanhystad
Thumbs Up tkinter canvas; different page sizes on different platforms? philipbergwerf 4 4,042 Mar-27-2021, 05:04 AM
Last Post: deanhystad
Star [Tkinter] How to perform math function in different page of Tkinter GUI ravaru 2 4,519 Oct-23-2020, 05:46 PM
Last Post: deanhystad
  [Tkinter] tkinter How to pass label fiilename to another module? johnjh 0 1,974 Apr-17-2020, 11:34 PM
Last Post: johnjh
  Tkinter: increasing numbers and Radiobutton issue PeroPuri 1 2,120 Apr-13-2020, 05:48 PM
Last Post: deanhystad
  Want to dynamically update numbers using tkinter in pygame script k0gane 0 2,035 Feb-09-2020, 09:01 AM
Last Post: k0gane
  [Tkinter] Result not change using Tkinter cmala 2 2,716 May-17-2019, 08:12 AM
Last Post: cmala

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020