我遇到了奇怪的问题。我的自动贩卖机上的tkinter
的GUI较为庞大。
Mya商品的ID从30到50。我想通过调用getPriceOfGivenID
方法来获取给定ID的价格。我的意思是,如果我按按钮3 + 1,我将正确获得31,因此我想通过单击proceed
按钮来获得31个项目的ID。可惜它抛出异常,不知道为什么。如果我从同一文件中调用函数,则从VendingMachine.py
中调用它会给我很好的结果。为什么会这样?
VendingMachine.py
from Coin import Coin
from Bank import Bank
from Item import Item
from decimal import *
from Automat import Automat
from tkinter import *
from tkinter import ttk
x1 = Coin(Decimal("0.01"))
x2 = Coin(Decimal("0.02"))
x3 = Coin(Decimal("0.05"))
x4 = Coin(Decimal("0.1"))
x5 = Coin(Decimal("0.2"))
x6 = Coin(Decimal("0.5"))
x7 = Coin(Decimal("1"))
x8 = Coin(Decimal("2"))
x9 = Coin(Decimal("5"))
listOfCoins = [x1, x2, x3, x4, x5, x6, x7, x8, x9]
bank = Bank()
for x in range(15):
for i in listOfCoins:
bank.addMoney(i)
Cola = Item(2) #cola prize is 2
Water = Item(1) #water prize is 1 etc.
Pepsi = Item(0.5)
SparklingWater = Item(0.25)
Cola2 = Item(1.3)
Cola3 = Item(2.5)
Cola4 = Item(2.45)
Cola5 = Item(3)
container = Automat(bank)
listOfItems = [Cola, Cola2, Cola3, Cola4, Cola5, Water, Pepsi, SparklingWater]
for i in listOfItems:
container.add_object(i)
gui = Tk()
gui.geometry('600x500')
gui.title("Vending Machine")
gui.configure(background="light green")
expression = ""
equation = StringVar()
expression_field = Entry(gui, textvariable=equation)
expression_field.grid(row=8, columnspan=4, ipadx=70)
equation.set('enter number of item')
labelOne = ttk.Label(gui, text='')
labelOne.grid(column=1, row=12)
labelTwo = ttk.Label(gui, text='')
labelTwo.grid(column=1, row=18)
def dropCoin(wartosc):
labelTwo.configure(text='Wrzucono: {0:0.2f}'.format(container.howManyCoinsWereDropped(wartosc)))
def getPriceOfGivenID():
a = equation.get()
print(a) # it gives good result, for example 30
labelOne.configure(text='You need to give: ' + container.find_price_of_given_id(a)) # it throws an exception
print(container.find_price_of_given_id(31)) # it gives good result
# Function to update expressiom
# in the text entry box
def press(num):
global expression
expression = expression + str(num)
equation.set(expression)
return expression
##### BUTTONS
button1 = Button(gui, text=' 1 ', fg='black', bg='red',
command=lambda: press(1), height=1, width=7)
button1.grid(row=2, column=0)
button2 = Button(gui, text=' 2 ', fg='black', bg='red',
command=lambda: press(2), height=1, width=7)
button2.grid(row=2, column=1)
button3 = Button(gui, text=' 3 ', fg='black', bg='red',
command=lambda: press(3), height=1, width=7)
button3.grid(row=2, column=2)
button4 = Button(gui, text=' 4 ', fg='black', bg='red',
command=lambda: press(4), height=1, width=7)
button4.grid(row=3, column=0)
button5 = Button(gui, text=' 5 ', fg='black', bg='red',
command=lambda: press(5), height=1, width=7)
button5.grid(row=3, column=1)
button6 = Button(gui, text=' 6 ', fg='black', bg='red',
command=lambda: press(6), height=1, width=7)
button6.grid(row=3, column=2)
button7 = Button(gui, text=' 7 ', fg='black', bg='red',
command=lambda: press(7), height=1, width=7)
button7.grid(row=4, column=0)
button8 = Button(gui, text=' 8 ', fg='black', bg='red',
command=lambda: press(8), height=1, width=7)
button8.grid(row=4, column=1)
button9 = Button(gui, text=' 9 ', fg='black', bg='red',
command=lambda: press(9), height=1, width=7)
button9.grid(row=4, column=2)
button0 = Button(gui, text=' 0 ', fg='black', bg='red',
command=lambda: press(0), height=1, width=7)
button0.grid(row=5, column=1)
mainframe = ttk.Frame(gui)
gui.mainloop()
Automat.py
from Item import Item
from NoItemException import NoItemException
from Bank import Bank
from Coin import Coin
from decimal import *
class Automat:
item_id = 30
def __init__(self, _bank, objects=None):
self.bank = _bank
if objects is None:
objects = {}
self.objects = objects
self._purchaseItemBank = []
def add_object(self, obj: Item):
id_to_assign = Automat.item_id
self.objects.update({id_to_assign: obj})
Automat.item_id = Automat.item_id + 1
return id_to_assign
def get_length(self):
return len(self.objects)
def find_price_of_given_id(self, item_id):
print(item_id) #it gives good passed item_id
if self.objects.get(item_id) is not None: #throw an exception if call from gui app, if call within normal way print(container.find_price_of_given_id(31)) gives good result
return self.objects.get(item_id).get_price()
else:
raise NoItemException
def find_amount_of_given_id(self, item_id):
if self.objects.get(item_id) is not None:
return self.objects.get(item_id).get_amount()
else:
raise NoItemException
如果我在VendingMachine.py
做这样的事情
print(container.find_price_of_given_id(31))
那我得到了很好的结果。
Stacktrace:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/Admin/PycharmProjects/vending-machine/VendingMachine.py", line 117, in <lambda>
command=lambda: getPriceOfGivenID(), height=1, width=7)
File "C:/Users/Admin/PycharmProjects/vending-machine/VendingMachine.py", line 62, in getPriceOfGivenID
labelOne.configure(text='Musisz wrzucić: ' + container.find_price_of_given_id(a))
File "C:\Users\Admin\PycharmProjects\vending-machine\Automat.py", line 32, in find_price_of_given_id
raise NoItemException
NoItemException.NoItemException
我也粘贴Item.py
,不知道是否需要,但是...:
class Item:
def __init__(self, price, amount=5):
self.amount = amount
self.price = price
def get_price(self):
return self.price
def get_amount(self):
return self.amount
def decrease(self):
self.amount -= 1
def __str__(self):
return f"{self.amount} @ {self.price}"
答案 0 :(得分:2)
这是类型不匹配的情况。特别是,您在objects
类中的字典Automat
使用int
作为键。稍后,当您执行查找时,您将使用equation.get()
传递的值。现在,equation
是一个StringVar
,当您对其执行str
时,它将返回get()
。
请注意,在python中,您可以使用带数字或字符串键的字典,但是它们是不同的键:
{'1': 'this key is a string', 1: 'this key is an int'}
进行修复的几种不同方法,但是从本质上讲,您需要确保使用int
执行查找。
一个例子是:
def getPriceOfGivenID():
a = int(equation.get())
... # rest of your core
或者,您可以在find_price_of_given_id
和find_amount_of_given_id
内进行转换,也可以更改add_object
方法并将键定义为str
。