[Tutor] Dynamic variables changed via Tkinter button

Jon Davies Jon_Davies17 at hotmail.co.uk
Wed Apr 15 16:09:21 EDT 2020


Hi,

As part of my Petrol Pay at Pump Tkinter GUI, I need to implement two labels (displaying dynamic variables) that will change based on a button being held.

The variables (counters) need to increase based on a calculation "Fuel amount in Litres * (Fuel Price * Chosen Currency)", as a "Fuel Lever" is pressed and held. I assume as part of the calculation, some sort of flow variable will be required, but not sure how best to implement this.

I've tried to implement the below so far, through defining the FUEL_PRICE_RATE, the various currencies and then implementing FUEL_LITRE_var and FUEL_PRICE_var as IntVars, which should then be updated through running a function def fuelHold - although I don't think I've actually configured this correctly.

This is is pure guesswork at the moment, so more looking for suggestions as to how this can be achieved, as I am getting basic errors e.g. . AttributeError: 'BeginFuellingPage' object has no attribute '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.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 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()

Thanks,

Jon


More information about the Tutor mailing list