Trying to make a text entry field with two buttons which will execute the same function for either object

Question:

I’m doing some hobby codes and am trying to make a GUI in python which will have, among other things, a text entry field which will allow the user to input a number of miles driven, then update the appropriate variable for whichever object is chosen by passing it through the method "drive" in the class "Vehicles"

When I run it, this is the error I get back:

Traceback (most recent call last): File "C:UsersjaredDocumentsCS
1030workspace codesHobby CodesClassPracticeTwo.py", line 72, in

MobileWindows() File "C:UsersjaredDocumentsCS 1030workspace codesHobby CodesClassPracticeTwo.py", line 55, in init
dodgeEntryButton = Button(frame2, text = "Dodge Drive", command = self.dodge.drive(driveEntry)) AttributeError: ‘MobileWindows’ object
has no attribute ‘dodge’

Here is my code:

#Classes practice

from tkinter import * #For the GUI

#creates the Vehicle class which has 3 attributes: name, mileage, and is_on
class Vehicle:
    def __init__(self, name, mileage, is_on):
        self.name = name
        self.mileage = mileage
        self.is_on = is_on

#Three functions: turn_on, turn_off, drive
    def turn_on(self): #Turns vehicle on if it was off
        if self.is_on is True:
            print("Nothing changes.")
        else:
            self.is_on = True
            print(f"The {self.name} roars to life!")

    def turn_off(self): #Turns vehicle off if it was on
        if self.is_on is True:
            self.is_on = False
            print(f"The {self.name} turns off.")
        else:
            print("Nothing changes.")

    def drive(self, miles): #Adds new miles to current mileage
        if self.is_on is True:
            self.mileage += miles
            print(f"The new mileage for the {self.name} is {self.mileage} miles.")
        else:
            print(f"The {self.name} is off. Turn it on before trying to drive!")

#class for the GUI
class MobileWindows:
    def __init__(self):
        window = Tk()
        window.title("Vehicle Interaction")

        #frame1 contains buttons for turning the dodge on and off and driving
        frame1 = Frame(window)
        frame1.pack()

        dodgeLabel = Label(frame1, text = "Dodge")
        onButton = Button(frame1, text = "Turn on", command = dodge.turn_on)
        offButton = Button(frame1, text = "Turn off", command = dodge.turn_off)

        dodgeLabel.pack()
        onButton.pack()
        offButton.pack()

        #frame2 contains the entry and buttons for the drive command
        frame2 = Frame(window)
        frame2.pack()

        driveLabel = Label(frame2, text = "Enter miles driven")
        self.entryMileage = IntVar()
        driveEntry = Entry(frame2, textvariable = self.entryMileage)
        dodgeEntryButton = Button(frame2, text = "Dodge Drive", command = Vehicle.drive(driveEntry))

        driveLabel.pack()
        driveEntry.pack()
        dodgeEntryButton.pack()

        window.mainloop()

#Creates two objects that can be used in commands
honda = Vehicle("Honda Civic", 40000, False)
dodge = Vehicle("Dodge Challenger", 50000, True)

MobileWindows()

I know a lot of my code may be inefficient, as I’m still very new to all this. I’m mainly just looking for how to resolve this error, but anything else is appreciated. Thanks!

Asked By: PBRjr

||

Answers:

You are pretty close. The issue is that you are struggling to pass arguments to the command attribute of the Button initializer. You should use a lambda, like so:

dodgeEntryButton = Button(frame2, text = "Dodge Drive", command = lambda : dodge.drive(self.entryMileage.get()))

lambda creates a little anonymous function like this:

def anonfunction():
    return dodge.drive(self.entryMileage.get())

And that’s what the command attribute sees. Since tkinter will only execute command as a function without arguments, this should work just fine for you.

Answered By: toppk
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.