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:\Users\jared\Documents\CS 1030\workspace codes\Hobby Codes\ClassPracticeTwo.py", line 72, in MobileWindows() File "C:\Users\jared\Documents\CS 1030\workspace codes\Hobby Codes\ClassPracticeTwo.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!
CodePudding user response:
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.