[Tutor] Dynamic variables changed via Tkinter button

Jon Davies jon_davies17 at hotmail.co.uk
Sat Apr 18 10:22:49 EDT 2020


Hi Alan,

As always, thanks for your insight - that gives me exactly the sort of base I was hoping to build on. I had researched on the web on whether it was possible, but given your note that typically this wouldn't considered as standard GUI behavior, explains why I maybe didn't find much (or perhaps I didn't look hard enough!).

I've now adapted the below and implemented something similar as part of my wider Petrol Pump program code and I've managed to get it functioning.

However, now I am looking to enhance this further (using the selected currency as input to a calculation, which you are already aware of).

Given I need two labels (one for Fuel Price, one for Litres), I've implemented two counts (fuelcount and pricecount) and separated these within the "update" function. For the pricecount, I am looking to enable an increase based on "fuelcount * (currency * petrol_price)".  See below for what I've tried to implement.

    def update(self):
        self.fuelcount += 0.1
        self.pricecount += 0.1 * (self.currency * PETROL_PRICE)
        self.litre_lbl['text'] = "Litres = %f" % self.fuelcount
        self.price_lbl['text'] = "Price = %f" % self.pricecount
        self.update_idletasks()
        if self.state == 'working':
            self.lever_btn.after(100, self.update)

I tried to configure the calculation to use the fuelcount value directly i.e. (0.1), but I found that this started to increase the pricecount exponentially, so for now I have just aligned the values at 0.1. The code doesn't seem to recognise self.currency (starting that AttributeError: 'BeginFuellingPage' object has no attribute 'currency'). If I replaced self.currency with a number, then it works.

I am trying to reference the currency variable that was set earlier on in the GUI via the SelectCurrencyPage.
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.setGBP(c))
        self.GBP_btn.pack()

        self.USD_btn = tk.Button(self, text = "$ USD",
                            command = lambda c = "$": self.setUSD(c))
        self.USD_btn.pack()

        self.EUR_btn = tk.Button(self, text = "€ EUR",
                            command = lambda c = "€": self.setEUR(c))
        self.EUR_btn.pack()

        self.restart_btn = tk.Button(self, text = _("RESTART"),
                            command = lambda: self.controller.setState('restart'))
        self.restart_btn.pack()

    def setGBP(self, currency):
        self.controller.setCurrency(GBP)
        self.controller.setState('fuel')

    def setUSD(self, currency):
        self.controller.setCurrency(USD)
        self.controller.setState('fuel')

    def setEUR(self, currency):
        self.controller.setCurrency(EUR)
        self.controller.setState('fuel')

Here are my constants:

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")

PETROL_PRICE = 1.17

GBP = 1.00
EUR = 1.14
USD = 1.24

And here is the setCurrency function that you helped define as part of the overarching app (Oleum) class, under the states:

class Oleum(tk.Tk):

#other code omitted to shorten email

    def setCurrency(self, c):
        self.currency = c

My other question would be how do I go about indicating the chosen currency symbol (£, $, €) on my "fueling" frame as part of the fuel price count label.

Kind regards,

Jon
________________________________
From: Tutor <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on behalf of Alan Gauld via Tutor <tutor at python.org>
Sent: 16 April 2020 12:53
To: tutor at python.org <tutor at python.org>
Subject: Re: [Tutor] Dynamic variables changed via Tkinter button

On 15/04/2020 21:09, Jon Davies wrote:
> I need to implement two labels (displaying dynamic variables) that will change based on a button being held.
Here is some runnable code that illustrates what you want, i think...

import tkinter as tk

class App():
    def __init__(self,parent):
         self.main = tk.Frame(parent)
         self.main.pack()
         self.state='idle'
         self.count = 0
         self.lbl = tk.Label(self.main, text="Count = 0")
         self.lbl.pack()
         self.btn = tk.Button(self.main, text="Press & Hold")
         self.btn.pack()
         self.btn.bind('<Button-1>', self.press)
         self.btn.bind("<ButtonRelease-1>", self.stop)

    def press(self,evt):
        self.state='working'
        self.btn.after(100,self.update)

    def update(self):
        self.count += 0.1
        self.lbl['text'] = "Count = %f" % self.count
        self.main.update_idletasks()
        if self.state == 'working':
            self.btn.after(100, self.update)

    def stop(self,evt):
        self.state = 'idle'

top = tk.Tk()
app = App(top)
top.mainloop()




--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

_______________________________________________________________________________________________________________________________________________________
From: Tutor <tutor-bounces+jon_davies17=hotmail.co.uk at python.org> on behalf of Alan Gauld via Tutor <tutor at python.org>
Sent: 16 April 2020 10:28
To: tutor at python.org <tutor at python.org>
Subject: Re: [Tutor] Dynamic variables changed via Tkinter button

On 15/04/2020 21:09, Jon Davies wrote:

> I need to implement two labels (displaying dynamic variables) that will change based on a button being held.

Working on the basis of a button being held is not normal GUI behaviour
so you won;t find any standard events to deal with that. Instead you
will need to look for mouse button events on the button.

So when the button is first pressed you need to start a pseudo
loop which performs the calculation and then pauses briefly
 - say for 50ms - then repeats until the mouse button up is
received.


So in your code you need to
1) bind the <ButtonPressed-1> and <ButtonRelease-1> events to your GUI
Button
2) On ButtonPressed set a state value of "fuelling"(or whatever you call
it)) Note this is a local state value in your Fuelling view, this is not
in the application level states table.(although it could be if you want.)
3) Start a loop using the after() method that checks the state for
fuelling and updates the label and then repeats the after() call.
If the state is not fuelling it updates the label and does not repeat
but calls your controller.setState() method to navigate to the
appropriate screen.
4) On ButtonReleased you change that state from "fuelling"

I think that is what you are trying to achieve...

So in pseudo code:

class Fuellingscreen(tk.Frame):
   def __init__(self,controller):
       ....
       self.fuelButton.bind(<ButtonPressed-1>, self.beginFuelling)
       self.fuelbutton.bind(<ButtonRelease-1>, self.endFuelling)
       set.state = 'idle'
       ...
   def beginFuelling(self):
       set label
       set self.state = 'fuelling'
       ... anything else....
       self.after(50,self.updateFuel)

   def updateFuel(self):
       do calculation
       update label
       self.update_idletasks()   # forces redraw of GUI
       if self.state == 'fuelling':
          self.after(50,self.updateFuel) #go again

   def endFuelling(self):
       self.state = 'idle'

Hopefully that's enough to get you started

BTW I didn't check the event names so you may need to look them up.


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



More information about the Tutor mailing list