modsbyus
Posts: 11
Joined: Fri Jul 03, 2015 11:34 pm

Trouble updating tkinter label with variable

Thu Jul 30, 2015 3:36 pm

I have been trying to create a label with tkinter that updates the value of the variable in textvariable from my temperature sensor (DS18B20) and displays it dynamically.
Here is two ways I have tried. The first works but is always creating a new label on top of the old label and would eventually cause the Pi to run out of memory.
The second never gives the updated label value on the GUI.

Code: Select all

#Updating Label Program

# Library Imports
import sys
from Tkinter import *
from w1thermsensor import W1ThermSensor


lGui = Tk()
lGui.geometry('240x50')
lGui.configure(background='black')
lGui.overrideredirect(False)
sensor = W1ThermSensor()
cntTemp = sensor.get_temperature(W1ThermSensor.DEGREES_F)
cTemp = cntTemp

def update():
    cntTemp = sensor.get_temperature(W1ThermSensor.DEGREES_F)
    cTemp = cntTemp
    #print(cTemp)
    labelFont = ("URW Chancery L", 45, 'bold', 'italic')
    tempLable = Label(lGui, text=cTemp, fg='white', bg='black', font=labelFont)
    tempLable.place(x=70,y=-5)
    lGui.update()
    lGui.after(500, update)
    
    
    

update()
lGui.mainloop()

Code: Select all

#Updating Label Program

# Library Imports
import sys
from Tkinter import *
from w1thermsensor import W1ThermSensor
import time, threading

sensor = W1ThermSensor()
cntTemp = sensor.get_temperature(W1ThermSensor.DEGREES_F)
cTemp = str(cntTemp)

lGui = Tk()
lGui.geometry('240x50')
lGui.configure(background='black')
lGui.overrideredirect(False)

labelFont = ("URW Chancery L", 45, 'bold', 'italic')
tempTemp = StringVar()
tempTemp.set(cTemp)
tempLable = Label(lGui, textvariable=tempTemp, fg='white', bg='black', font=labelFont)
tempLable.place(x=70,y=-5)

lGui.after(250,tempTemp.set(cTemp))
lGui.mainloop()

User avatar
paddyg
Posts: 2360
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Trouble updating tkinter label with variable

Thu Jul 30, 2015 7:54 pm

Could you make the variables you're getting lots of instances of global so the allocation of the symbol to a new instance drops the old one? (Asuming tk doesn't keep a reference somewhere) - I don't really like this recursive repeat system but it does seem to be a standard method with tk.

PS I'm pretty sure there's a standard way of just changing the text of a tk Label - have you searched for that?
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

modsbyus
Posts: 11
Joined: Fri Jul 03, 2015 11:34 pm

Re: Trouble updating tkinter label with variable

Thu Jul 30, 2015 8:18 pm

Would you explain what you mean here.
Could you make the variables you're getting lots of instances of global so the allocation of the symbol to a new instance drops the old one?
PS I'm pretty sure there's a standard way of just changing the text of a tk Label - have you searched for that?
I have done quite a bit of searching. From what I can tell, you use text= for a static label entry and textvariable= for variable updated text in the label.
Like so.....

Code: Select all

tempTemp = StringVar()
tempTemp.set(cTemp)
tempLable = Label(lGui, textvariable=tempTemp, fg='white', bg='black', font=labelFont)
I have also tried updating the gui

Code: Select all

lGui.update()
and

Code: Select all

lGui.after(250,tempTemp.set(cTemp),tempLable.update())

User avatar
paddyg
Posts: 2360
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Trouble updating tkinter label with variable

Thu Jul 30, 2015 10:09 pm

By creating new instances inside the function python will keep duplicates even though they have the same name (each function will have it's own "name-space",python has special rules that seem to confuse pretty much everyone). You can force it to overwrite by using global, or, better, avoid creating instances inside the function. I've not tested this so it's probably got errors but hopefully you get the general idea.

Code: Select all

#Updating Label Program

# Library Imports
import sys
from Tkinter import *
from w1thermsensor import W1ThermSensor

lGui = Tk()
lGui.geometry('240x50')
lGui.configure(background='black')
lGui.overrideredirect(False)
sensor = W1ThermSensor()
tempTemp = StringVar()
labelFont = ("URW Chancery L", 45, 'bold', 'italic')
tempLable = Label(lGui, textvariable=tempTemp, fg='white', bg='black', font=labelFont)
tempLable.place(x=70,y=-5)

def update():
    global tempTemp, IGui, sensor # you don't really need to declare these as global because doing it this way gets rid of the ambiguity
    tempTemp.set(sensor.get_temperature(W1ThermSensor.DEGREES_F))
    lGui.update()
    lGui.after(500, update)

update()
lGui.mainloop()
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

modsbyus
Posts: 11
Joined: Fri Jul 03, 2015 11:34 pm

Re: Trouble updating tkinter label with variable

Fri Jul 31, 2015 2:45 am

paddyg, Thank you!
I have been at this a week and have only seen one thing about using global and I don't think that was in relation to my particular issue. That worked like a charm. Now Ican finally get back to building my thermostat!

wolf_ykaaaaa
Posts: 1
Joined: Sat Feb 25, 2017 6:25 pm

Re: Trouble updating tkinter label with variable

Sat Feb 25, 2017 6:31 pm

Hi. I'm trying to write a small cpu temperature monitor program. No matter how I try. I have already tried a lot of solutions but it did not help. Only label refreshing would not work. Please someone help me because this is my last chance :( Thank you in advance.


from Tkinter import *
import os
import time
import subprocess
from subprocess import *
import sys



ablak1 = Tk()
ablak1.geometry('540x100')
ablak1.configure(background='black')
ablak1.overrideredirect(False)
tempTemp = StringVar()
labelFont = ("URW Chancery L", 45, 'bold', 'italic')
tempLable = Label(ablak1, textvariable=tempTemp, fg='white', bg='black', font=labelFont)
tempLable.place(x=70,y=-5)

def getCPUtemperature():
res = os.popen('vcgencmd measure_temp').readline()
return(res.replace("temp=","").replace("'C\n"," Celsius"))

cputemp = getCPUtemperature()

def update():
global tempTemp, ablak1, cputemp, label1 # you don't really need to declare these as global because doing it this wa$
tempTemp.set(cputemp)
ablak1.update()
ablak1.after(500, update)

Code: Select all

[code]
[/code]

update()
ablak1.mainloop()

User avatar
paddyg
Posts: 2360
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Trouble updating tkinter label with variable

Sun Feb 26, 2017 8:06 am

i dont think anyone will help unless you sort out your code tags.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

User avatar
RogerW
Posts: 285
Joined: Sat Dec 20, 2014 12:15 pm
Location: London UK

Re: Trouble updating tkinter label with variable

Sun Feb 26, 2017 5:25 pm

You could try something allong these lines.

Code: Select all

import tkinter as tk

class Mainframe(tk.Frame):
    # Mainframe contains the widgets
    # More advanced programs may have multiple frames
    # or possibly a grid of subframes
    
    def __init__(self,master,*args,**kwargs):
        # *args packs positional arguments into tuple args
        # **kwargs packs keyword arguments into dict kwargs
        
        # initialise base class
        tk.Frame.__init__(self,master,*args,**kwargs)
        # in this case the * an ** operators unpack the parameters
        
        # put your widgets here
        self.Temperature = tk.IntVar()
        tk.Label(self,textvariable = self.Temperature).pack()
        self.TimerInterval = 500
        
        # variable for dummy GetTemp
        self.Temp = 0
        
        # call Get Temp which will call itself after a delay
        self.GetTemp()
        
    def GetTemp(self):
        ## replace this with code to read sensor
        self.Temperature.set(self.Temp)
        self.Temp += 1
        
        # Now repeat call
        self.after(self.TimerInterval,self.GetTemp)
   
class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
               
        # set the title bar text
        self.title('CPU Temperature Demo')
        # Make sure app window is big enough to show title 
        self.geometry('300x100')
      
        # create and pack a Mainframe window
        Mainframe(self).pack()
        
        # now start
        self.mainloop()
                    
# create an App object
# it will run itself
App()

Return to “Python”