Я создаю GUI в Python / Tkinter для приложения Petrol Pay-at-Pump. Частью приложения является экран «Цена / объем топлива» и имитация топливного насоса (в будущем я надеюсь, что это будет ie эта физическая кнопка с RaspberryPi / макет и т. Д. c.).
TL: DR; Мне нужна кнопка (fuel_lever), чтобы при нажатии / удерживании она обновляла две переменные (FUEL_LITRE и FUEL_PRICE), а затем две метки Tkinter (fuel_litre_lbl и fuel_price_lbl), основываясь на следующем:
- FUEL_LITRE: Рандомизированное инкрементное увеличение (как кажется, попытка выбросить поток топлива в смесь может сделать слишком трудным)
- FUEL_PRICE: FUEL_LITRE * (FUEL_PRICE_RATE x Выбранная валюта (c), которая была выбрана ранее в приложении и определена как GBP , EUR и USD)
Мой вопрос состоит в том, как мне реализовать динамические переменные c FUEL_LITRES и FUEL_PRICE (как метки, которые меняются в зависимости от удерживаемого fuel_lever), а также с учетом выбрана валюта в расчет? (ПОЖАЛУЙСТА, ИГНОРИРУЙТЕ преамбулы _ () вокруг строк, это используется для разрешения перевода 'gettext'.
Извлечение того, что я пытаюсь реализовать (как часть полного кода), которое производит хост ошибок (в основном потому, что на данный момент это просто догадки, поэтому больше ищите предложений относительно того, как этого можно достичь). Например:
AttributeError: У объекта 'BeginFuellingPage' нет атрибута 'FUEL_LITRE'
import tkinter as tk
from tkinter import ttk
import gettext
#Constants
FUEL_PRICE_RATE = 1.17
GBP = 1.00
EUR = 1.14
USD = 1.24
class SelectCurrencyPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.GBP_btn = tk.Button(self, text = "£ GBP",
command = lambda c = "£": self.doCurrency(GBP))
self.GBP_btn.pack()
self.USD_btn = tk.Button(self, text = "$ USD",
command = lambda c = "$": self.doCurrency(USD))
self.USD_btn.pack()
self.EUR_btn = tk.Button(self, text = "€ EUR",
command = lambda c = "€": self.doCurrency(EUR))
self.EUR_btn.pack()
def doCurrency(self, currency):
self.controller.setCurrency(currency)
class BeginFuellingPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.fuel_litre_lbl = tk.Label(self, textvariable = self.FUEL_LITRE, font = LARGE_FONT)
self.fuel_litre_lbl.pack(pady = 10, padx = 10)
self.fuel_price_lbl = tk.Label(self, textvariable = self.FUEL_PRICE, font = LARGE_FONT)
self.fuel_price_lbl.pack(pady = 10, padx = 10)
self.FUEL_LITRE = tk.IntVar(self, value = 0)
self.FUEL_PRICE = tk.IntVar(self, value = 0)
self.fuel_lever_btn = tk.Button(self, text = _("FUEL LEVER"),
command = self.fuelHold)
self.fuel_lever_btn.pack()
def fuelHold(self):
self.begin_fuel_lbl.config(text = _("FUELLING IN PROGRESS"))
self.restart_btn.destroy()
self.FUEL_LITRE.set(FUEL_LITRE.get() + 0.352)
self.FUEL_PRICE.set(FUEL_PRICE.get() + (FUEL_PRICE_RATE * c))
class Oleum(tk.Tk):
def setCurrency(self, c):
self.currency = c
Полный код ниже
import tkinter as tk
from tkinter import ttk
import gettext
#Constants
LARGE_FONT = ("Arial", 12)
MEDIUM_FONT = ("Arial", 9)
DARK_PURPLE = ("#7030a0")
LIGHT_PURPLE = ("#9f60ce")
FUEL_PRICE_RATE = 1.17
GBP = 1.00
EUR = 1.14
USD = 1.24
class SelectLanguagePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.lang_lbl = tk.Label(self, text = "PLEASE SELECT LANGUAGE", font = LARGE_FONT)
self.lang_lbl.pack(pady = 10, padx = 10)
self.EN_lang_btn = tk.Button(self, text = "ENGLISH",
command = lambda: self.set_language("ENGLISH"))
self.EN_lang_btn.pack()
self.DE_lang_btn = tk.Button(self, text = "DEUTSCH",
command = lambda: self.set_language("GERMAN"))
self.DE_lang_btn.pack()
self.ES_lang_btn = tk.Button(self, text = "ESPAÑOL",
command = lambda: self.set_language("SPANISH"))
self.ES_lang_btn.pack()
self.FR_lang_btn = tk.Button(self, text = "FRANÇAIS",
command = lambda: self.set_language("FRENCH"))
self.FR_lang_btn.pack()
def set_language(self, lang):
locales = {
"ENGLISH" : "en",
"GERMAN" : "de",
"SPANISH" : "es",
"FRENCH" : "fr"
}
lang_file = "res/messages_{}.mo".format(locales[lang])
self.trans = gettext.GNUTranslations(open(lang_file,'rb'))
self.trans.install()
self.controller.setFrames()
self.controller.setState('language')
class SelectPaymentPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.controller = controller
self.select_payment_lbl = tk.Label(self, text = _("SELECT PAYMENT OPTION"), font = LARGE_FONT)
self.select_payment_lbl.pack(pady = 10, padx = 10)
self.pap_btn = tk.Button(self, text = _("PAY-AT-PUMP"),
command = lambda: self.controller.setState("pump"))
self.pap_btn.pack()
self.pak_btn = tk.Button(self, text = _("PAY-AT-KIOSK"),
command = lambda: self.controller.setState("kiosk"))
self.pak_btn.pack()
self.restart_btn = tk.Button(self, text = _("RESTART"),
command = lambda: self.controller.setState("restart"))
self.restart_btn.pack()
class InsertCardPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.insert_card_lbl = tk.Label(self, text = _("PLEASE INSERT CARD"), font = LARGE_FONT)
self.insert_card_lbl.pack()
self.insert_card_btn = tk.Button(self, text = _("INSERT CARD"),
command = self.card_read)
self.insert_card_btn.pack()
self.restart_btn = tk.Button(self, text = _("RESTART"),
command = lambda: self.controller.setState('restart'))
self.restart_btn.pack()
def delay(self):
app.after(2000, self.controller.setState('currency'))
self.insert_card_btn.config(state = 'active')
def card_read(self):
self.insert_card_lbl['text'] = _("CARD READ")
app.after(2000, self.delay)
self.insert_card_btn.config(state='disabled')
self.restart_btn.destroy()
class SelectCurrencyPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.currency_lbl = tk.Label(self, text = _("PLEASE SELECT CURRENCY"), font = LARGE_FONT)
self.currency_lbl.pack(pady = 10, padx = 10)
self.GBP_btn = tk.Button(self, text = "£ GBP",
command = lambda c = "£": self.doCurrency(c))
self.GBP_btn.pack()
self.USD_btn = tk.Button(self, text = "$ USD",
command = lambda c = "$": self.doCurrency(c))
self.USD_btn.pack()
self.EUR_btn = tk.Button(self, text = "€ EUR",
command = lambda c = "€": self.doCurrency(c))
self.EUR_btn.pack()
self.restart_btn = tk.Button(self, text = _("RESTART"),
command = lambda: self.controller.setState('restart'))
self.restart_btn.pack()
def doCurrency(self, currency):
self.controller.setCurrency(currency)
self.controller.setState('fuel')
class BeginFuellingPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.begin_fuel_lbl = tk.Label(self, text = _("BEGIN FUELLING"), font = LARGE_FONT)
self.begin_fuel_lbl.pack(pady = 10, padx = 10)
self.fuel_litre_lbl = tk.Label(self, textvariable = self.FUEL_LITRE_var, font = LARGE_FONT)
self.fuel_litre_lbl.pack(pady = 10, padx = 10)
self.fuel_price_lbl = tk.Label(self, textvariable = self.FUEL_PRICE_var, font = LARGE_FONT)
self.fuel_price_lbl.pack(pady = 10, padx = 10)
self.FUEL_LITRE_var = tk.IntVar(self, value = 0)
self.FUEL_PRICE_var = tk.IntVar(self, value = 0)
self.fuel_lever_btn = tk.Button(self, text = _("FUEL LEVER"),
command = self.fuelHold)
self.fuel_lever_btn.pack()
self.finish_btn = tk.Button(self, text = "FINISH",
command = self.doFinish)
self.finish_btn.pack()
self.restart_btn = tk.Button(self, text = _("RESTART"),
command = lambda: self.controller.setState('restart'))
self.restart_btn.pack()
def fuelHold(self):
self.begin_fuel_lbl.config(text = _("FUELLING IN PROGRESS"))
self.restart_btn.destroy()
self.FUEL_LITRE_var.set(FUEL_LITRE_var.get() + fuel flow?)
self.FUEL_PRICE_var.set(FUEL_PRICE_var.get() + (FUEL_PRICE_RATE * currency?))
def doFinish(self):
self.begin_fuel_lbl.config(text = _("FUELLING COMPLETE"))
self.lever_btn.config(state='active')
self.finish_btn.config(state='disabled')
self.controller.setState('finish')
class TotalGoodbyePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.goodbye_lbl = tk.Label(self, text = _("THANK YOU, GOODBYE"), font = LARGE_FONT)
self.goodbye_lbl.pack(pady = 10, padx = 10)
self.restart_btn = tk.Button(self, text = _("RESTART"),
command = lambda: self.controller.setState('restart'))
self.restart_btn.pack()
class Oleum(tk.Tk):
states = {
SelectLanguagePage: {
'cancel' : SelectLanguagePage,
'language' : SelectPaymentPage
},
SelectPaymentPage: {
'restart' : SelectLanguagePage,
'pump' : InsertCardPage,
'kiosk' : SelectCurrencyPage,
'other' : SelectPaymentPage
},
InsertCardPage: {
'restart' : SelectLanguagePage,
'currency' : SelectCurrencyPage,
'other' : InsertCardPage
},
SelectCurrencyPage: {
'restart' : SelectLanguagePage,
'fuel' : BeginFuellingPage,
'other' : SelectCurrencyPage
},
BeginFuellingPage: {
'restart' : SelectLanguagePage,
'finish' : TotalGoodbyePage,
'other' : BeginFuellingPage
},
TotalGoodbyePage: {
'any' : SelectLanguagePage
}
}
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.events = self.states.keys()
self.currentState = SelectLanguagePage
self.currency = None
self.container = tk.Frame(self)
self.container.grid(row=0,column=0,sticky='news')
view = SelectLanguagePage(self.container,self)
view.grid(row=0,column=0,sticky='news')
self.frames = {SelectLanguagePage : view}
self.show_frame()
def setFrames(self):
for F in ( SelectPaymentPage, InsertCardPage,
SelectCurrencyPage, BeginFuellingPage, TotalGoodbyePage):
view = F(self.container,self)
view.grid(row=0,column=0,sticky='news')
self.frames[F] = view
def show_frame(self, view=None):
if view == None: view = self.currentState
frame = self.frames[view]
frame.tkraise()
def setState(self,event):
self.currentState = self.states[self.currentState].get(event, SelectLanguagePage)
self.show_frame()
def setCurrency(self, c):
self.currency = c
if __name__ == "__main__":
app = Oleum()
app.title('Oleum')
app.configure(background = DARK_PURPLE)
app.geometry("420x380")
app.resizable(0,0)
app.mainloop()