[Tutor] Pay-at-Pump Use Case - Tkinter GUI
Jon Davies
Jon_Davies17 at hotmail.co.uk
Sun Feb 23 08:10:02 EST 2020
Hi all,
I'm completely new to programming, Python and the like. I've researched various modules and frameworks, and am beginning to feel overwhelmed with the hundreds of ways in which to create a (hopefully) basic functioning application.
In short, my aim is to create a GUI app that mimics a Pay-At-Pump software application which navigates multiple screens depending on options selected, following a simple flow e.g. Select Language > Select Payment Method > Insert Card > Select Currency > Begin Fuelling > Fuelling In Progress > Total and Goodbye. Semantics wise, I'd love to be able to make it look fantastic, but for now, I want to make sure I can develop something that works. Ideally, this is being built to deploy onto a Raspberry Pi, as I was planning to (hopefully) use a touchscreen to provide input to the GUI, and a breadboard with a push button to provide the input (simulate a fuel pump) – however, this is not a priority as such!
I’ve been following some video tutorials and other online resources to get to a stage where I have created a VERY basic GUI which can navigate through multiple pages based on clicking a button, however I need to enhance this with some of the other features. The key parts of functionality for me concern the language translation of the entire app, and the calculation of fuel price based on an input multiplied by a set of currency exchange rates (depending on which is selected).
For translation, I am struggling to find the right way in which to present the rest of the app in a different language, based on the button pressed on the first frame. Having googled, there were a couple of different solutions but I couldn’t seem to apply them to my code.
My baseline code is below:
class Oleum(tk.Tk):
def __init__(self, *args, **kwargs): #
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (SelectLanguagePage, SelectPaymentPage, InsertCardPage, SelectCurrencyPage, BeginFuellingPage, FuellingInProgressPage, TotalGoodbyePage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column = 0, sticky = "nsew")
self.show_frame(SelectLanguagePage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
I tried to create lists containing the string input for every single label and button for each frame. At the moment, I have put prompt labels on the first frame (SelectLanguagePage) in all languages with a button to select each respective language.
#LANGUAGE DICTIONARY - 17 ITEMS TOTAL
ENGLISH = ['WELCOME!', 'SELECT YOUR LANGUAGE', 'SELECT PAYMENT METHOD', 'PAY-AT-PUMP', 'PAY-AT-KIOSK', 'PLEASE INSERT CARD', 'PLEASE SELECT CURRENCY', '£ GBP', '$ USD',
'€ EUR', 'BEGIN FUELLING', 'TOTAL FUEL', 'TOTAL COST', 'FUELLING IN PROGRESS', 'FINISH', 'THANK YOU, GOODBYE']
GERMAN = ['DAS WILLKOMMEN!', 'WÄHLE DEINE SPRACHE', 'ZAHLUNG AUSWÄHLEN METHODE', 'PAY-AT-PUMP', 'PAY-AT-KIOSK', 'BITTE KARTE EINFÜGEN', 'BITTE WÄHLEN SIE IHRE WÄHRUNG', '£ GBP', '$ USD',
'€ EUR', 'TANKEN BEGINNEN', 'GESAMTKRAFTSTOFF', 'GESAMTKOSTEN', 'TREIBEN IM FORTSCHRITT', 'FERTIG', 'DANKE. AUF WIEDERSEHEN']
SPANISH = ['¡BIENVENIDA!', 'ELIGE TU IDIOMA', 'SELECCIONAR PAGO MÉTODO', 'PAGO EN BOMBA', 'PAGO EN EL KIOSCO', 'INSERTE LA TARJETA', 'POR FAVOR SELECCIONE SU MONEDA', '£ GBP', '$ USD',
'€ EUR', 'COMENZAR COMBUSTIBLE', 'COMBUSTIBLE TOTAL', 'COSTE TOTAL', 'COMBUSTIBLE EN PROGRESO', 'TERMINAR', 'GRACIAS, ADIOS']
FRENCH = ['BIENVENUE!', 'CHOISISSEZ VOTRE LANGUE', 'CHOISIR LE PAIEMENT MÉTHODE', 'PAYER À LA POMPE', 'PAYER AU KIOSQUE', 'VEUILLEZ INSÉRER LA CARTE', 'VEUILLEZ SÉLECTIONNER VOTRE MONNAIE', '£ GBP', '$ USD',
'€ EUR', 'COMMENCER LE CARBURANT', 'CARBURANT TOTAL', 'COÛT TOTAL', 'RAVITAILLEMENT EN COURS', 'TERMINER', 'MERCI, AU REVOIR']
class SelectLanguagePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
EN_lang_prompt = tk.Label(self, text = "PLEASE SELECT LANGUAGE", font = LARGE_FONT) #tk.Label is the class, the object is label
EN_lang_prompt.pack(pady = 10, padx = 10)
DE_lang_prompt = tk.Label(self, text = "WÄHLE DEINE SPRACHE", font = LARGE_FONT)
DE_lang_prompt.pack(pady = 10, padx = 10)
ES_lang_prompt = tk.Label(self, text = "ELIGE TU IDIOMA", font = LARGE_FONT)
ES_lang_prompt.pack(pady = 10, padx = 10)
FR_lang_prompt = tk.Label(self, text = "CHOISISSEZ VOTRE LANGUE", font = LARGE_FONT)
FR_lang_prompt.pack(pady = 10, padx = 10)
EN_lang_button = tk.Button(self, text = "ENGLISH",
command = lambda: controller.show_frame(SelectPaymentPage))
EN_lang_button.pack()
DE_lang_button = tk.Button(self, text = "GERMAN",
command = lambda: controller.show_frame(SelectPaymentPage))
DE_lang_button.pack()
ES_lang_button = tk.Button(self, text = "SPANISH",
command = lambda: controller.show_frame(SelectPaymentPage))
ES_lang_button.pack()
FR_lang_button = tk.Button(self, text = "FRENCH",
command = lambda: controller.show_frame(SelectPaymentPage))
FR_lang_button.pack()
The aim is to show SelectPaymentPage (and essentially all subsequent pages as defined in frames (F) in baseline code) in the desired language as selected via the buttons in 1st Frame. Again, I assume this would involve passing multiple commands through lambda to show the 2nd frame, pull in the values from my language lists etc.)
How best would I achieve this, in a way that I can then replicate for each frame? My current basic code for 2nd frame is below.
class SelectPaymentPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text = "SELECT PAYMENT OPTION", font = LARGE_FONT)
label.pack(pady = 10, padx = 10)
pap_button = tk.Button(self, text = "PAY-AT-PUMP",
command = lambda: controller.show_frame(InsertCardPage))
pap_button.pack()
pap_button = tk.Button(self, text = "PAY-AT-KIOSK",
command = lambda: controller.show_frame(SelectCurrencyPage))
pap_button.pack()
button1 = tk.Button(self, text = "RESTART",
command = lambda: controller.show_frame(SelectLanguagePage))
button1.pack()
I’d found the following online, but as mentioned above I have struggled to apply this in my scenario:
Changing the language is as simple as modifying each Tk widget depending on the selected language. For example,
def change_language(lang):
if lang == 'English':
root.title('Program')
menuButton.config(text='Menu')
elif lang == 'Spanish':
root.title('Programa')
menuButton.config(text='Menú')
To make it easier to write the code, you could store your language data in a file (e.g. csv), parse it into lists or dictionaries, and have something like this:
english = ['Program', 'Menu']
spanish = ['Programa', 'Menú']
def change_language_2(lang):
root.title(lang[0])
menuButton.config(text=lang[1])
Any help would be greatly appreciated, as in theory once I know the specific code structure/command/variables required, I should be able to then take this an apply it where necessary.
Kind regards,
Jon
More information about the Tutor
mailing list