Python Forum
Tkinter: How to assign calculated value to a Label
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tkinter: How to assign calculated value to a Label
#1
I'm using Python3.8 for my raspberry pi4 project. I have a GUI that initially displays the label within a grid. I also have a button that when clicked, should display the calculated value of CO2 in the label. However, it does not display the CO2 value and there is no error flagged. Below is my code snippet (I removed others as they're not relevant to this question):

frame2 = Frame(root)
lblCo2 = Label(frame2, text="CO2 (ppm)")
lblCo2.grid(row=4, sticky=W)
valCo2 = Label(frame2, bg="white", width=12)
valCo2grid(row=4, column=1, sticky=W)

btnStart = Button(frame2, text="Start", command=btnStart_callback)
btnStart.grid(row=5, column=1, sticky=W)
frame2.pack()

def btnStart_callback():
    CycleCO2()

def CycleCO2():
    Cmd1 = [0xFE, 0x44, 0x00, 0x08, 0x02, 0x9F, 0x25)
    high = Cmd1[3]
    low = Cmd1[4]
    co2 = (high*256) + low
    
    valCo2 = tk.Label(frame2, text=co2)
Appreciate any help.
Reply
#2
Since you've not shown all the code, one is having to guess a bit. On line 20, you assign to valCo2, but then you never do anything with that variable. Do you need to redraw the frame or something?

Also, why do you need btnStart_callback? Why not just pass CycleCO2 itself on line 7?
Reply
#3
In addition, make sure you add a grid statement to valCo2
Reply
#4
Post the bare minimum runnable code showing the problem at hand.
Dont use * imports see Namespace flooding with * imports
Create the label once and then change it's text value in the buttons event handler.
Use a class to easily keep a reference to GUI widgets.

See below code
import tkinter as tk


class Main:
    def __init__(self, root):
        self.frame = tk.Frame(root)
        lblCo2 = tk.Label(self.frame, text="CO2 (ppm)")
        lblCo2.grid(row=4, sticky=tk.W)
        self.valCo2 = tk.Label(self.frame, bg="white", width=12)
        self.valCo2.grid(row=4, column=1, sticky=tk.W)

        btnStart = tk.Button(self.frame, text="Start",
                             command=self.on_btn_start)
        btnStart.grid(row=5, column=1, sticky=tk.W)
        self.frame.pack()

    def on_btn_start(self):
        Cmd1 = [0xFE, 0x44, 0x00, 0x08, 0x02, 0x9F, 0x25]
        high = Cmd1[3]
        low = Cmd1[4]
        co2 = (high*256) + low
        self.valCo2['text'] = co2


root = tk.Tk()
main = Main(root)
root.mainloop()
Reply
#5
Hi y'all,

This is my first post to this Forum, so I'm not sure how to respond individually. Also new to Python.

I've hooked up a CO2 sensor to the raspberry pi4 monitor. The app is supposed to read data from CO2 sensor. Eventually, I need to create a real-time line chart to show the data coming from the CO2 sensor. For now, I'm just trying to get a single CO2 reading and display it on the valCo2 label. I've written a desktop PC equivalent of this app using VB.Net language. I'm slowly trying to convert my codes to Python.

Here's my full code so far:

import serial, sys, glob, select
import time
import matplotlib.pyplot as plt
import tkinter as tk
import numpy as np

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *
from tkinter import messagebox
from itertools import count
from matplotlib.animation import FuncAnimation
from pandas import DataFrame

#Create line chart data
co2Data = {"Time": [1920,1930,1940,1950,1960,1970,1980,1990,2000,2010],
           "CO2 ppm": [9.8,12,8,7.2,6.9,7,6.5,6.2,5.5,6.3]
          }

#Create a DataFrame
df = DataFrame(co2Data, columns=["Time", "CO2 ppm"])

#Create a display window
root = Tk()    
root.wm_title("Soil CO2 Logger" )
root.geometry("800x480")

def btnStart_callback():    
    CycleCO2()
   
def btnExit_callback():
    root.destroy()
   
#CO2 Sensor Functions

def CycleCO2():
    #Connect to a serial port: serial device and baudrate
    dev = "/dev/ttyUSB0"
    scan = glob.glob(dev)
    rate = "9600"
   
    if(len(scan) == 0):
        dev = '/dev/ttyUSB*'
        scan = glob.glob(dev)
       
        if(len(scan) == 0):
            messagebox.showerror("Error","Unable to find any ports. Scanning for /dev/[ttyACM*|ttyUSB*]") + dev
            sys.exit()
   
    serport = scan[0]
   
    if(len(sys.argv) > 1):
        l = len(sys.argv) - 1
        while( l > 0):
            if(sys.argv[l][0] == '/'):
               serport = sys.argv[l]
            else:
                l = l - 1
   
    ser = serial.Serial(
        port = serport,
        baudrate = rate,
        parity = serial.PARITY_NONE,
        stopbits = serial.STOPBITS_ONE,
        bytesize = serial.EIGHTBITS,
        timeout = 1)
       
    Cmd1 = [0xFE, 0x44, 0x00, 0x08, 0x02, 0x9F, 0x25]
   
    while True:              
       
        ser.flushInput()
        ser.write(Cmd1)
        time.sleep(1.9)

        high = Cmd1[3]
        low = Cmd1[4]
        co2 = (high*256) + low            
        time.sleep(.1)
           
        valCo2 = tk.Label(frame2, text = str(co2) ) 

   
#Plot line chart
fig1 = plt.Figure(figsize=(5,4), dpi=100)
ax1 = fig1.add_subplot(111)
line1 = FigureCanvasTkAgg(fig1, root)
line1.get_tk_widget().pack(side=LEFT, fill=Y)
df = df[["Time", "CO2 ppm"]].groupby("Time").sum()
df.plot(kind="line", legend=True, ax = ax1, color = "b", marker = "o", fontsize = 10)
ax1.set_title("CO2 ppm vs. Time")

frame1 = Frame(root)
lblReadings = Label(frame1, text="CO2 Readings")
lblReadings.grid(row=0, column=0, sticky=W)

lboxResult = Listbox(frame1, width=35)
lboxResult.grid(row=1, sticky=W)
frame1.pack()

frame2 = Frame(root)

lblCoffee = Label(frame2, text="Coffee Break:")
lblCoffee.grid(row=0, sticky=W)
entCoffee = Entry(frame2, width= 12)
entCoffee.grid(row=0, column=1, sticky=W)

lblSample = Label(frame2, text="Sample #:")
lblSample.grid(row=1, sticky=W)
entSample = Entry(frame2, width= 12)
entSample.grid(row=1, column=1,sticky=W)

lblTestTime = Label(frame2, text="Test Time (hh:mm:ss)")
lblTestTime.grid(row=2, sticky=W)
entTestTime = Entry(frame2, width= 12)
entTestTime.grid(row=2, column=1, sticky=W)

lblPeakTime = Label(frame2, text="Countdown to Peak Time")
lblPeakTime.grid(row=3, sticky=W)
entPeakTime = Entry(frame2, width= 12)
entPeakTime.grid(row=3, column=1, sticky=W)

lblCo2 = Label(frame2, text="CO2 (ppm)")
lblCo2.grid(row=4, sticky=W)
valCo2 = Label(frame2, bg="white", width=12)
valCo2.grid(row=4, column=1, sticky=W)

lblPeakCaptured = Label(frame2, text="Peak Captured @ 30-second")
lblPeakCaptured.grid(row=5, sticky=W)
entPeakCaptured = Entry(frame2, width= 12)
entPeakCaptured.grid(row=5, column=1, sticky=W)
frame2.pack()


frame3 = Frame(root)
img = PhotoImage(file="off_bulb.png")
canvas = Canvas(frame3, width=70, height=70)
canvas.create_image(10,10, anchor=NW, image=img)
canvas.pack()
canvas.grid(row=0, column=0, sticky=W)

btnStart = Button(frame3, text="Start", command=btnStart_callback)
btnStart.grid(row=0, column=1, sticky=W)

btnStop = Button(frame3, text="Stop")
btnStop.grid(row=0, column=2, sticky=W)

btnExit = Button(frame3, text="Exit", command=btnExit_callback)
btnExit.grid(row=0, column=3, sticky=W)

frame3.pack()

root.mainloop()
Reply
#6
I wanted to check Yoriz' suggestion as having helped me a lot. I wasn't using classes, so that's a step in the right direction. However, there's no button on this site to select the suggestion that helps (unlike in other forum sites, e.g., Microsoft Developers Network).

I added a reputation point to Yoriz, just to show my gratitude.

I haven't fully solved this yet. It's not posting the value to the label but funny, when I add a messagebox just to see if there's a value read from the sensor, the value is then posted to the label when I click the "OK" button on the messagebox. Obviously, I still need to work on this.

But I followed Yoriz's advise to create classes to make it easier and I'm getting there.

Thanks.
Reply
#7
You don't like the Rep or Like buttons that appear at the bottom of every post?

Unlike stackoverflow, this forum thinks the participants can make up their own mind about what answers are good and which are bad. It is very Pythonic.
Reply
#8
Okay. I got it to work:

1. I removed the "while true" statement in the CycleCO2 function.
2. I replaced the following statement:
valCo2 = tk.Label(frame2, text = str(co2) )

with

 self.valCo2.config(text = co2)
Now it displays the value when click the "Start" button.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  tkinter: Image to Label Maryan 10 482 Oct-29-2020, 01:48 PM
Last Post: joe_momma
  Tkinter - How can I extend a label widget? TurboC 2 309 Oct-13-2020, 12:15 PM
Last Post: zazas321
  changing tkinter label from thread nanok66 3 868 Jun-07-2020, 01:37 AM
Last Post: nanok66
  [Tkinter] tkinter How to pass label fiilename to another module? johnjh 0 558 Apr-17-2020, 11:34 PM
Last Post: johnjh
  Make Label Text background (default color) transparent using tkinter in python barry76 1 9,847 Nov-28-2019, 10:19 AM
Last Post: Larz60+
  Spacing Between two labels are very far and Top label is not in Center using Tkinter barry76 2 1,951 Jul-30-2019, 10:49 AM
Last Post: wuf
  Unable to update or refresh label text in tkinter jenkins43 3 2,905 Jul-24-2019, 02:09 PM
Last Post: Friend
  tkinter label error nonzzo 1 1,671 Mar-31-2019, 01:29 PM
Last Post: Larz60+
  [Tkinter] TkInter toggle Label on/off MTom5 2 2,986 Aug-15-2018, 12:35 AM
Last Post: metulburr
  [PyQt] Assign Label Text as number in Hz mekha 17 3,895 Jul-18-2018, 12:47 AM
Last Post: mekha

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020