0

I am trying to measure some value with sensors and display it using python tkinter GUI. I managed to create a GUI and the program to measure. Now I want to display the data in the GUI and as I am getting new values every second I want to update the screen with new values. I have seen than I can use textvariable. But how to initialize this? when program start, as there is no any output in the beginning, it shows error. How to manage it. any suggestions please. finally how to update every second?

from tkinter import * import tkinter.font import numpy as np import pigpio win = Tk() myFont = tkinter.font.Font(family = 'Verdana', size = 20, weight = 'bold') win.geometry('800x480') win.configure(background='#CD5C5C') #------------------------------------------------------main program ----------------------------------# def readSensors(): #function body # output is a list with name measuredValues #measuredValues contains total 4 values as I have 4 sensors win.after(1000, readSensors) #calling the function every second #label names variable output_1= StringVar() output_2 = StringVar() output_3 = StringVar() output_4 = StringVar() value0 = str(measuredValues[0]) value1= str(measuredValues[1]) value2 = str(measuredValues[2]) value3 = str(measuredValues[3]) output_1.set (value0) output_2.set (value1) output_3.set (value2) output_4.set(value3) #Labels # i used textvariable to to measured values. but doesn't work so far #display values output_1_label = Label(win, textvariable = output_1,height =2, width = 12) output_1_label.place(x=200, y=100) output_2_label = Label(win, textvariable = output_2, height =2, width = 12) output_2_label.place(x=200, y=200) output_3_label = Label(win, textvariable = output_3,height =2, width = 12) output_3_label.place(x=200, y=300) output_4_label = Label(win, textvariable = output_4, height =2, width = 12) output_4_label.place(x=200, y=400) #how to update the window with new data? win.after(1000, readSensor) win.mainloop() 

2 Answers 2

1

You need to update the variables set as textvariables with the sensor values last read:

Something like this - the sensor readings were replaced with a randomly chosen value to simulate new data readings:

import tkinter as tk import random def readSensors(): output_1.set(random.choice([0, 1, 2, 3, 4, 5])) output_2.set(random.choice([0, 1, 2, 3, 4, 5])) output_3.set(random.choice([0, 1, 2, 3, 4, 5])) output_4.set(random.choice([0, 1, 2, 3, 4, 5])) win.after(1000, readSensors) win = tk.Tk() win.geometry('800x480') win.configure(background='#CD5C5C') output_1 = tk.StringVar() output_2 = tk.StringVar() output_3 = tk.StringVar() output_4 = tk.StringVar() measuredValues = [0, 1, 2, 3, 4, 5] value0 = str(measuredValues[0]) value1 = str(measuredValues[1]) value2 = str(measuredValues[2]) value3 = str(measuredValues[3]) output_1.set(value0) output_2.set(value1) output_3.set(value2) output_4.set(value3) output_1_label = tk.Label(win, textvariable=output_1, height=2, width=12) output_1_label.place(x=200, y=100) output_2_label = tk.Label(win, textvariable=output_2, height=2, width=12) output_2_label.place(x=200, y=200) output_3_label = tk.Label(win, textvariable=output_3, height=2, width=12) output_3_label.place(x=200, y=300) output_4_label = tk.Label(win, textvariable=output_4, height=2, width=12) output_4_label.place(x=200, y=400) win.after(1000, readSensors) win.mainloop() 
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. it works :). One more doubt. is it possible to add a start button and a stop button in tkinter to start and stop the measurement?
`startButton = Button(win, text = "Start")´ and some function to start the measurement?
You are welcome. Yes, it is possible; I suggest that you try, and if you face difficulties, please feel free to ask a new question. something like this: start_button = tk.Button(win, text="Start", command=start_recording_measurements)
Could you please have a look at this link --> stackoverflow.com/q/56937694/11372345
0

You can use Classes to reach all the data from parent structure. You need to initilize a function to call another function with after tribute inside it first. It simply configures the data again and again after counting firstly 1000 ms and then 20 ms(adjust it to read data smoothly). You can add more dynamic data/text and use "after" tribute once, it will still be refreshing all of them. It is an event dependent solution which is significantly better than time dependent or loop based refreshing algorithms for data reading.

import time from random import random from random import seed from tkinter import StringVar,Entry import tkinter as tk class GUI: #------------------INITIAL--------------------------------------------------------------------------------------------------------- def __init__(self, parent): self.labelBackground = tk.Label(parent, text="",bg="white",width=1920,height=1080) self.labelBackground.place(x=0,y=0) self.labelDate = tk.Label(parent, text="Date",bg="white", font="Arial 20", width=100) self.labelDate.pack() self.labelDate.after(1000, self.refresh_label) def dateData(self): year,mon,day,hour,min,sec,a,b,c = time.localtime() infoDate = f"Date/Time: {year} {mon} {day} h:{hour} m:{min} s:{sec} " return f"Clock: {hour}:{min}:{sec} " def refresh_label(self): self.seconds = self.dateData() self.labelDate.configure(text=self.seconds) self.labelDate.after(20, self.refresh_label) if __name__ == "__main__": root = tk.Tk() root.geometry("1920x1080") #Window Resolution root.title("Insert_Window_Title") timer = GUI(root) root.mainloop() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.