0

Hello,

Im trying to make a simple equation solver with tkinter. Originally i built it without using classes and it worked fine however I am now trying to use a class.

from tkinter import *
import math

class RootFinder(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        self.root1lbl=Label(self.outputframe, text='')
        self.root1lbl.grid(row=0,column=1)

        self.root2lbl=Label(self.outputframe,text='')
        self.root2lbl.grid(row=0, column=4)

        self.calcbutton=Button(self.inputframe, text="Calculate Roots",\
                               command=self.findroots())
        self.calcbutton.grid(row=1, column=5, padx=20)

    def findroots(self):
        sqr=self.sqrcoeff.get()
        xcoeff=self.xcoeff.get()
        const=self.constant.get()

        a=float(sqr)
        b=float(xcoeff)
        c=float(const)

        root1=round((-b+math.sqrt(b*b-4*a*c))/(2*a),3)
        root2=round((-b-math.sqrt(b*b-4*a*c))/(2*a),3)
        self.root1lbl.configure(text=root1)
        self.root2lbl.configure(text=root2)

app=RootFinder()
app.mainloop()

Ive only shown the widgets concerned. The problem is that it doesnt like me trying to configure the root1 and root2 labels and I really don't know why. This is the output when run:

Traceback (most recent call last):
File "C:/Python32/Programs/new class.py", line 83, in <module>
app=RootFinder()
File "C:/Python32/Programs/new class.py", line 9, in __init__
self.create_widgets()
File "C:/Python32/Programs/new class.py", line 37, in create_widgets
command=self.findroots())
File "C:/Python32/Programs/new class.py", line 80, in findroots
RootFinder.root1lbl.configure(text=root1)
AttributeError: type object 'RootFinder' has no attribute 'root1lbl'


Any help is appreciated thanks.

4
Contributors
10
Replies
11
Views
5 Years
Discussion Span
Last Post by pyTony
Featured Replies
0

We really need the whole code.

Or at least try to replace RootFinder.root1lbl.configure(text=root1) with self.root1lbl.configure(text=root1)

Edited by vegaseat: n/a

0

But one sure thing is that you are calling findroots instead of giving findroots method as parameter in line 37 in error message, line 18 in posted code.

0

There are a lot of problems with the code you posted:

## there is no root window
app=RootFinder()
app.mainloop()
#----------  should be 
root = Tk()
app=RootFinder(root)
root.mainloop()
#
## self.outputframe is never declared in the code you posted
    def create_widgets(self):
        self.root1lbl=Label(self.outputframe, text='')

And that is all that I care to examine at this point. See Ene Uran's example for starters.

Edited by woooee: n/a

0

Here is the full code:

from tkinter import *
import math
import cmath

class RootFinder(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        self.labelf=Label(self, text="What is f(x)?", font='Arial 10 bold', pady=5)
        self.labelf.grid(sticky='w')
        
        self.inputframe=Frame(self)
        self.inputframe.grid(row=1, columnspan=5)
        
        self.sqrcoeff=Entry(self.inputframe, width=5)
        self.sqrcoeff.grid(row=1, column=0)
        self.sqrcoeff.insert(0, '1')
        
        self.xsqrlabel=Label(self.inputframe, text="x\u00B2 + ")
        self.xsqrlabel.grid(row=1, column=1)

        self.xcoeff=Entry(self.inputframe, width=5)
        self.xcoeff.grid(row=1, column=2)
        self.xcoeff.insert(0, '0')
        
        self.xlabel=Label(self.inputframe, text="x + ")
        self.xlabel.grid(row=1, column=3)
        
        self.constant=Entry(self.inputframe, width=5)
        self.constant.grid(row=1, column=4)
        self.constant.insert(0, '0')
        
        self.calcbutton=Button(self.inputframe, text="Calculate Roots",\
                               command=self.findroots())
        self.calcbutton.grid(row=1, column=5, padx=20)
        
        self.outputframe=Frame(self)
        self.outputframe.grid(row=2, columnspan=5)
        
        self.rootlabel=Label(self.outputframe, text="x = ")
        self.rootlabel.grid(row=0,column=0)
        
        self.root1lbl=Label(self.outputframe, text='       ')
        self.root1lbl.grid(row=0,column=1)
        
        self.orlabel=Label(self.outputframe,text=" or ")
        self.orlabel.grid(row=0, column=2)
        
        self.root2lbl=Label(self.outputframe,text='       ')
        self.root2lbl.grid(row=0, column=4)

    def findroots(self):
        sqr=self.sqrcoeff.get()
        xcoeff=self.xcoeff.get()
        const=self.constant.get()
        
        if sqr == "" or sqr == "0":
            messagebox.showinfo(message="This is not a quadratic equation")

        else:
            a=float(sqr)
            b=float(xcoeff)
            c=float(const)

        if b*b-4*a*c < 0:  #for complex roots
            root1=(-b+cmath.sqrt(b*b-4*a*c))/(2*a)
            root2=(-b-cmath.sqrt(b*b-4*a*c))/(2*a)
            re1, im1=round(root1.real,3), round(root1.imag,3)
            re2, im2=round(root2.real,3), round(root2.imag,3)
            root1, root2=complex(re1,im1), complex(re2,im2)
            self.root1lbl.configure(text=root1)
            self.root2lbl.configure(text=root2)

        else:      #for real roots
            root1=round((-b+math.sqrt(b*b-4*a*c))/(2*a),3)
            root2=round((-b-math.sqrt(b*b-4*a*c))/(2*a),3)
            self.root1lbl.configure(text=root1)
            self.root2lbl.configure(text=root2)

app=RootFinder()
app.mainloop()

In response to woooee, I had said in my previus post that i had only shown relevant widgets.

0

Instead of 84 lines of code, with no idea what the problem is, compose the program in steps and test after each step. To get you started: (note the difference between final three lines here, and your code).

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

import math
import cmath

class RootFinder():
    def __init__(self, master=None):
        self.fr = tk.Frame(master)
        self.fr.grid()
        self.create_widgets()

    def create_widgets(self):
        self.labelf=tk.Label(self.fr, text="What is f(x)?", font='Arial 10 bold', pady=5)
        self.labelf.grid(row=0, column=0, sticky='w')

        self.sqrcoeff=tk.Entry(self.fr, width=5)
        self.sqrcoeff.grid(row=1, column=0)
        self.sqrcoeff.insert(0, '1')

root = tk.Tk()
RF = RootFinder(root)
root.mainloop()

Edited by woooee: n/a

0

After your suggestion I added each line of code at a time...
It didnt like it when lines 74,75 and 80,81 were added

0

In your button you are calling
command=self.findroots()
it needs to be a reference, not a call
command=self.findroots

0

Right Tony! A mistake frequently made by beginners to Tkinter. The error message is often confusing in this case.

0

Problem with these "procedural functions" which do not at least say: "wrong number of parameters". One place where there would be really benefit for type check. (until you want to use function returning function, like decorated function)

Edited by pyTony: n/a

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.