Search code examples
pythontkinterraspberry-piraspberry-pi3gpio

Python Tkinter using Raspberry Pi updating GUI


recently i have been working on Tkinter in Raspberry pi to build a GUI for home automation, and i wanted to design a validation module which says "ACTIVE" when the sensor is working and "INACTIVE" when sensor has malfunctioned. I am able to get the validation in the GUI but its not dynamic. Every time i have to re-run the program to get the updated status of the sensors

is there a way where in i can update the Active and Inactive status without re-running the entire program?

I am taking input from GPIO pins on the raspberry pi and reading them in the program

here is the code i have worked on so far:

import RPi.GPIO as GPIO
import time
from tkinter import *
from tkinter import ttk
import tkinter.font


GPIO.setwarnings(False)


Sig1 = 7
GPIO.setmode(GPIO.BOARD)
GPIO.setup(Sig1, GPIO.IN)

out1 = 11# pin11
GPIO.setmode(GPIO.BOARD) # We are accessing GPIOs according to their physical location
GPIO.setup(out1, GPIO.OUT) # We have set our LED pin mode to output
GPIO.output(out1, GPIO.LOW)

gui = Tk()
gui.title("tkinter")
gui.config(background = "gray86")
gui.minsize(1050,620)

Font1 = tkinter.font.Font(family = 'Courier 10 Pitch', size = 20, weight = 'bold')
Font2 = tkinter.font.Font(family = 'Courier 10 Pitch', size = 18, weight = 'bold')
Font3 = tkinter.font.Font(family = 'Courier 10 Pitch', size = 9, weight = 'bold')

def func1_on():
    GPIO.output(out1, GPIO.HIGH) # led on
    Text1 = Label(gui,text=' ON ', font = Font2, bg = 'gray84', fg='green3', padx = 0)
    Text1.grid(row=8,column=1)

def func1_off():
    GPIO.output(out1, GPIO.LOW) # led off
    Text2 = Label(gui,text='OFF', font = Font2, bg = 'gray84', fg='red', padx = 0)
    Text2.grid(row=8,column=1)

label_2 = Label(gui,text='Sensor:', font = Font2, fg='gray40', bg = 'gray84', padx = 10, pady = 10)
label_2.grid(row=6,column=0)

if GPIO.input(Sig1) == True:
    Text3 = Label(gui,textvariable=' Active ',relief = "raised", font = Font2, bg = 'gray84', fg='green3', padx = 0)
    Text3.grid(row=6,column=1)
else:
    Text4 = Label(gui,textvariable=' Inactive ',relief = "raised", font = Font2, bg = 'gray84', fg='red', padx = 0)
    Text4.grid(row=6,column=1)


Button1 = Button(gui, text='Switch On', font = Font3, command = func1_on, bg='gray74', height = 1, width = 7)
Button1.grid(row=8,column=0)
Button2 = Button(gui, text='Switch Off', font = Font3, command = func1_off, bg='gray74', height = 1, width = 7)
Button2.grid(row=9,column=0)

gui.mainloop()

it would be greatly appreciated if someone could help me with this.


Solution

  • Use root.after(milliseconds, function_name) run some function periodically.

    This function should check sensors, update text in labels and use root.after to run again after some time.

    BTW: function_name should be without ()


    Minimal example. It updates label with current time

    import tkinter as tk
    import time
    
    # --- functions ---
    
    def check():
        # update text in existing labels
        label['text'] = time.strftime('%H:%M:%S')
    
        # run again after 1000ms (1s)
        root.after(1000, check) 
    
    # --- main ---
    
    root = tk.Tk()
    
    label = tk.Label(root)
    label.pack()
    
    check() # run first time
    
    root.mainloop()