1

So I am creating a Python Tkinter application, which has a measured value I need displayed to the screen every second. When the program runs, the value show, but it isn't updating (I am externally manipulating the value so I know the display should be changing). How do I get the display to dynamically update every second? I was made to understand that I didn't need to create an Update() method or anything for Tkinter applications because mainloop() takes care of that. Here is my code:

Main.py:

from SimpleInterface import SimpleInterface
from ADC import Converter, Differential

adc = Converter(channelNums = [2])

root = SimpleInterface(adc)
root.title = ("Test Interface")

root.mainloop()

SimpleInterface.py:

import tkinter as tk
from tkinter import ttk

class SimpleInterface(tk.Tk):

    def __init__(self, ADC, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self, *args, **kwargs)
        container.grid(column = 0, row = 0, sticky = "nwes")
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        frame = Screen(ADC, container, self)
        frame.grid(row = 0, column = 0, sticky = "nsew")
        frame.tkraise()

class Screen(tk.Frame):

    def __init__(self, ADC, parent, controller):
        tk.Frame.__init__(self, parent)

        displayText = ADC.ReadValues() #this method returns a list of values
        for i in range(len(displayText)):
            displayText[i] = round(displayText[i], 2)
        ttk.Label(self, text = "Test Display", background = "grey").grid(column = 7, row = 8)
        lblTestDisplay = ttk.Label(self, text = displayText, foreground = "lime", background = "black").grid(column = 7, row = 9, sticky = "ew")

So the display properly shows the displayText when the code is initially run, but again nothing changes as I manually manipulate the value being input. Do I need to create an Update() method? If so where would I call said method?

1 Answer 1

3

Yes, you will need to create a method to update the values, and add that method to the tkinter mainloop with after. I'd recommend naming it something else, because update is already a tkinter method.

As a totally untested guess:

class Screen(tk.Frame):
    def __init__(self, ADC, parent, controller):
        tk.Frame.__init__(self, parent)
        self.ADC = ADC
        lbl = ttk.Label(self, text = "Test Display", background = "grey")
        lbl.grid(column = 7, row = 8)
        self.lblTestDisplay = ttk.Label(self, foreground = "lime", background = "black")
        self.lblTestDisplay.grid(column = 7, row = 9, sticky = "ew")

        self.adc_update() # start the adc loop

    def adc_update(self):
        displayText = self.ADC.ReadValues() #this method returns a list of values
        for i in range(len(displayText)):
            displayText[i] = round(displayText[i], 2)
        self.lblTestDisplay.config(text = str(displayText)) # update the display
        self.after(1000, self.adc_update) # ask the mainloop to call this method again in 1,000 milliseconds

Note I also split your label creation into 2 lines, one to initialize and one to layout. The way you had it is very bad; it leads to the variable assigned to None which leads to bugs.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. And I wasn't aware that the way I had the initialize and layout caused a None variable. I'll have to remember that for the future. Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.