Raspberry Pi Python Tkinter image flicker problem - python

This is my first post and I have googled extensively for an answer but found nothing that works. I'm new to python but have some experience with C++/arduino programming.
I'm trying to make a weather station and display some garage door states as image icons. My issue is when it works, it flickers the images and eventually bogs down the system and runs very slowly. I've tried every combination I can think of making objects global or only changing certain parameters in the Label objects to work around the garbage collection issue I've read about. I've tried Canvas as well, but the issue I had with that is no matter what location coordinates I entered, it always showed up in the top center of the screen.
Edit: as per requested, heres a truncated version:
root = tk.Tk()
global garageOpenIcon
global garageClosedIcon
global doorUnlockedIcon
global doorLockedIcon
global doorOpenIcon
backgroundImage = PhotoImage(file = "background.gif")
garageOpenIcon = PhotoImage(file = "garageOpen.gif")
garageClosedIcon = PhotoImage(file = "garageClosed.gif")
doorLockedIcon = PhotoImage(file = "doorLocked.gif")
doorUnlockedIcon = PhotoImage(file = "doorUnlocked.gif")
doorOpenIcon = PhotoImage(file = "doorOpen.gif")
background = Label(root, image = backgroundImage)
background.place(x = 0, y = 0, relwidth = 1, relheight = 1)
global mainDoorLabel
global sideDoorLabel
mainDoorLabel = Label(root)
sideDoorLabel = Label(root)
def getDoors():
global garageOpenIcon
global garageClosedIcon
global doorOpenIcon
global doorUnlockedIcon
global doorLockedIcon
global mainDoorLabel
global sideDoorLabel
#side door open and unlocked:
if(GPIO.input(sideDoorPin) == GPIO.HIGH):
sideDoorLabel = Label(image = doorOpenIcon)
#closed and unlocked:
elif(GPIO.input(sideDoorPin) == GPIO.LOW):
if(GPIO.input(sideDoorLockPin) == GPIO.HIGH):
sideDoorLabel = Label(image = doorUnlockedIcon)
elif(GPIO.input(sideDoorPin) == GPIO.LOW):
sideDoorLabel = Label(image = doorLockedIcon)
#main door:
if(GPIO.input(mainDoorPin) == GPIO.HIGH):
mainDoorLabel = Label(image = garageOpenIcon)
else:
mainDoorLabel = Label(image = garageClosedIcon)
mainDoorLabel.place(x = 50, y = 400)
sideDoorLabel.place(x = 150, y = 400)
root.after(1000, getDoors)
Here is my full code, images work but flicker:
# WeatherStation for Raspberry Pi Model B Rev 2
# steve.a.mccluskey#gmail.com
#
# Code adapted from youtube.com/watch?v=MWKAitSX3vg
# Channel educ8s.tv
# Video name "Raspberry Pi Project: Touch Weather Station using a DHT22 and a Raspberry Pi 3 with TKInter GUI
#
# This program uses readings from several Dallas DS18B20 temp sensors and displays on the LCD along with on a website.
# Temps are collected from a background process called updateSensors.py and written to a JSON file called sensorValues.JSON
# which is located in the web folder at /var/www/html/. This program reads the JSON file. The webpage also reads it so there's
# minimal interferance between programs.
# Sensors are zero indexed. The sensors are assigned to their respective labels by their index number.
# Use readSensors.py to print their index number, digital ID and current temp to the console.
#
# Door sensors are read directly from this program and displayed accordingly. updateDoor.py is also run in background to write to doorSensorValues.json
# also in the web folder to be served to the web page.
#
# Hardware Used:
# Raspberry Pi Model B Rev 2
# Adafruit PITFT - Assembled 480x320 3.5" TFT+Touchscreen For Raspberry Pi, adafruit.com/product/2097
# Adafruit Prototyping Pi Plate Kit for Raspberry Pi, adafruit.com/product/801
# Sparkfun RJ45 Breakout sparkfun.com/products/716
# Sparkfun RJ45 8-Pin Connector sparkfun.com/products/643
# Dallas OneWire DS18B20 Digital Temp Sensors
#
#
#
#
# ------------
# GPIO Pins used:
# 1 ) 3.3v -> orange -> 3.3v
# 2 ) 5.0v
# 3 ) SDA -> white/brown -> I2C SDA
# 4 ) 5.0v
# 5 ) SCL -> brown -> I2C SCL
# 6 ) Gnd -> white/orange -> Gnd
# 7 ) GPIO 7 -> GPIO 4 -> white/green -> OneWire Bus
# 8 ) TXD
# 9 ) Gnd
# 10) RXD
# 11) GPIO 0 -> GPIO 17
# 12) GPIO 1 -> GPIO 18
# 13) GPIO 2 -> GPIO 27 -> blue -> Main Door Sensor
#
# 14) Gnd
# 15) GPIO 3 -> GPIO 22 -> white/blue -> Side Door Sensor
# 16) GPIO 4 -> GPIO 23 -> green -> Side Door Lock Sensor
# 17) 3.3v
# 18) GPIO 5 -> GPIO 24 -> LCD Shield
# 19) SPI MOSI -> LCD Shield
# 20) Gnd
# 21) SPI MISO -> LCD Shield
# 22) GPIO 6 -> GPIO 25 -> LCD Shield
# 23) SPI SCLK -> LCD Shield
# 24) SPI CE0 -> LCD Shield
# 25) Gnd
# 26) SPI CE1 -> LCD Shield
# -------
# Cat5e Pinout :
# White/Orange : Gnd
# Orange : 3.3v
# White/Green : OneWire
# Blue : Main Door Sensor
# White/Blue : Side Door Sensor
# Green : Side Door Lock Sensor
# White/Brown : I2C SDA
# Brown : I2C SCL
from Tkinter import *
import Tkinter as tk
from Tkinter import Canvas
from PIL import ImageTk, Image
import threading
import tkFont
import RPi.GPIO as GPIO
import json
import time
import datetime
#temp sensor assignments:
livingRoom = 1
upstairs = 4
basement = 0
outside = 2
garage = 3
sammyDoor = 5
#digital door sensor pins:
mainDoorPin = 27
sideDoorPin = 22
sideDoorLockPin = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(mainDoorPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(sideDoorPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(sideDoorLockPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
root = tk.Tk()
global garageOpenIcon
global garageClosedIcon
global doorUnlockedIcon
global doorLockedIcon
global doorOpenIcon
backgroundImage = PhotoImage(file = "background.gif")
garageOpenIcon = PhotoImage(file = "garageOpen.gif")
garageClosedIcon = PhotoImage(file = "garageClosed.gif")
doorLockedIcon = PhotoImage(file = "doorLocked.gif")
doorUnlockedIcon = PhotoImage(file = "doorUnlocked.gif")
doorOpenIcon = PhotoImage(file = "doorOpen.gif")
background = Label(root, image = backgroundImage)
background.place(x = 0, y = 0, relwidth = 1, relheight = 1)
global mainDoorLabel
global sideDoorLabel
global mainDoorState
global sideDoorState
mainDoorLabel = Label(root)
sideDoorLabel = Label(root)
#mainDoorLabel.place(x = 50, y = 400)
#sideDoorLabel.place(x = 150, y = 400)
#temp sensor strings:
mainTemp = StringVar()
mainTemp.set("In: ")
mainTempValue = StringVar()
outTemp = StringVar()
outTemp.set("Out:")
LR = StringVar()
LR.set("Living Room: ")
temperatureLR = StringVar()
UP = StringVar()
UP.set("Upstairs: ")
temperatureUp = StringVar()
DN = StringVar()
DN.set("Basement: ")
temperatureDn = StringVar()
Out = StringVar()
Out.set("Outside: ")
temperatureOut = StringVar()
Garage = StringVar()
Garage.set("Garage: ")
temperatureGg = StringVar()
SammyDoor = StringVar()
SammyDoor.set("SammyDoor: ")
temperatureSammyDoor = StringVar()
currentTime = StringVar()
timeStamp = StringVar()
#temp sensor labels:
mainTempLabel = Label(root, fg = "magenta2", background = "#00dbde", textvariable = mainTemp, font = ("Helvetica", 30))
mainTempLabel.place(x = 20, y = 195)
mainTempValueLabel = Label(root, fg = "magenta2", background = "#00dbde", textvariable = mainTempValue, font = ("Helvetica", 62, "bold"))
mainTempValueLabel.place(x = 100, y = 170)
outTempLabel = Label(root, fg = "magenta2", background = "#00dbde", textvariable = outTemp, font = ("Helvetica", 30))
outTempLabel.place(x = 20, y = 300)
outTempValueLabel = Label(root, fg = "magenta2", background = "#00dbde", textvariable = temperatureOut, font = ("Helvetica", 62, "bold"))
outTempValueLabel.place(x = 100, y = 260)
currentTimeLabel = Label(root, fg = "purple", background = "#00dbde", textvariable = currentTime, font = ("Helvetica", 30))
currentTimeLabel.place(x = 270, y = 5)
LRLabel = Label(root, fg = "white", background = "#00dbde", textvariable = LR, font = ("Helvetica", 25))
LRLabel.place(x = 391, y = 160)
temperatureLRLabel = Label(root, fg = "white", background = "#00dbde", textvariable = temperatureLR, font = ("Helvetica", 25, "bold"))
temperatureLRLabel.place(x = 600, y = 160)
UPLabel = Label(root, fg= "white", background = "#00dbde", textvariable = UP, font = ("Helvetica", 25))
UPLabel.place(x = 391, y = 210)
temperatureUpLabel = Label(root, fg = "white", background = "#00dbde", textvariable = temperatureUp, font = ("Helvetica", 25, "bold"))
temperatureUpLabel.place(x = 600, y = 210)
DNLabel = Label(root, fg = "white", background = "#00dbde", textvariable = DN, font = ("Helvetica", 25))
DNLabel.place(x = 391, y = 260)
temperatureDnLabel = Label(root, fg = "white", background = "#00dbde", textvariable = temperatureDn, font = ("Helvetica", 25, "bold"))
temperatureDnLabel.place(x = 600, y = 260)
GarageLabel = Label(root, fg = "white", background = "#00dbde", textvariable = Garage, font = ("Helvetica", 25))
GarageLabel.place(x = 391, y = 310)
temperatureGgLabel = Label(root, fg = "white", background = "#00dbde", textvariable = temperatureGg, font = ("Helvetica", 25, "bold"))
temperatureGgLabel.place(x = 600, y = 310)
SammyDoorLabel = Label(root, fg = "white", background = "#00dbde", textvariable = SammyDoor, font = ("Helvetica", 25))
SammyDoorLabel.place(x = 391, y = 360)
temperatureSammyDoorLabel = Label(root, fg = "white", background = "#00dbde", textvariable = temperatureSammyDoor, font = ("Helvetica", 25, "bold"))
temperatureSammyDoorLabel.place(x = 600, y = 360)
timeStampLabel = Label(root, fg = "white", background = "#00dbde", textvariable = timeStamp, font = ("Helvetica", 15))
timeStampLabel.place(x = 530, y = 440)
root.attributes("-fullscreen", True)
exitButton = tk.Button(root,fg = "white", text = "X", font = ("Helvetica", 20, "bold"), command = exit, bg = "red")
exitButton.place(x = 680, y = 0)
root.update_idletasks()
def exit():
root.quit()
def updateTemps():
index_value = []
id_value = []
temp_value = []
dateTime_value = []
#try reading json file. will not read if it is being written to by background process updateSensors.py
try:
with open('/var/www/html/sensorValues.json', 'r') as f:
data = f.read()
dataString = json.loads(data)
f.close()
for dateTime in dataString['timestamp']:
dateTime_value = (dateTime['dateTime'])
for index in dataString['sensors']:
temp_value.append(index['temp'])
id_value.append(index['id'])
index_value.append(index['index'])
temperatureLR.set(str(temp_value[livingRoom]) + " F")
temperatureOut.set(str(temp_value[outside]) + " F")
temperatureGg.set(str(temp_value[garage]) + " F")
temperatureUp.set(str(temp_value[upstairs]) + " F")
temperatureDn.set(str(temp_value[basement]) + " F")
temperatureSammyDoor.set(str(temp_value[sammyDoor]) + " F")
timeStamp.set(str(dateTime_value))
avg = format(float(((float(temp_value[livingRoom]) + float(temp_value[upstairs])) / 2.0)), '.1f')
mainTempValue.set(str(avg) + " F")
except:
pass
root.after(2000, updateTemps)
def getDoors():
global garageOpenIcon
global garageClosedIcon
global doorOpenIcon
global doorUnlockedIcon
global doorLockedIcon
global mainDoorLabel
global sideDoorLabel
# sideDoorState = 0
# mainDoorState = 0
#side door open and unlocked:
if(GPIO.input(sideDoorPin) == GPIO.HIGH):
# sideDoorState = 2
sideDoorLabel = Label(image = doorOpenIcon)
#closed and unlocked:
elif(GPIO.input(sideDoorPin) == GPIO.LOW):
if(GPIO.input(sideDoorLockPin) == GPIO.HIGH):
# sideDoorState = 1
sideDoorLabel = Label(image = doorUnlockedIcon)
elif(GPIO.input(sideDoorPin) == GPIO.LOW):
# sideDoorState = 0
sideDoorLabel = Label(image = doorLockedIcon)
#main door:
if(GPIO.input(mainDoorPin) == GPIO.HIGH):
# mainDoorState = 1
mainDoorLabel = Label(image = garageOpenIcon)
else:
mainDoorState = 0
mainDoorLabel = Label(image = garageClosedIcon)
mainDoorLabel.place(x = 50, y = 400)
sideDoorLabel.place(x = 150, y = 400)
root.after(1000, getDoors)
def getTime():
currentTime.set(datetime.datetime.now().strftime("%m-%d-%Y %H:%M:%S"))
root.after(500, getTime)
root.after(1000, getTime)
root.after(1001, updateTemps)
root.after(1000, getDoors)
root.mainloop()

maindoorlabel.configure(image = garageopenicon)
maindoorlabel.image = garageopenicon worked.

Related

Guizero textbox focus

I am a newb and I have a small script that uses guizero to create a small app that reads a rfid tag and activates door lock. The problem I am having is, when the power goes off and the raspberry pi reboots. the script launches but I have to manually click in the texts box before it will start working. how can I have it automatically set focus on the textbox when it launches?
thanks
Mark
Here is code, I found this project online and modified some to work for me.
from gpiozero import LED, Buzzer
from guizero import App, Box, Text, TextBox, warn
import gpiozero
import csv
RELAY_PIN = 17
led8 = LED(5)
led9 = LED(6)
relay= gpiozero.OutputDevice(RELAY_PIN,active_high=False, initial_value=False)
def clearDisplay():
print("Clear display")
rfidStatus.value = "—"
rfidText.value = ""
led8.off()
led9.off()
relay.off()
rfidStatus.repeat(1000, checkRFidTag)
def checkRFidTag():
tagId = rfidText.value
if tagId != "":
RFidRegistered = False
print(tagId)
with open("Database.csv") as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
if row["RFid"] == tagId:
RFidRegistered = True
print("Welcome " + row["User"])
rfidStatus.value = "Welcome " + row["User"]
led8.on()
relay.toggle()
rfidStatus.after(5000, clearDisplay)
if RFidRegistered == False:
print("RFid tag is not registered")
rfidStatus.value = "RFid tag is not registered"
led9.on()
rfidStatus.after(3000, clearDisplay)
rfidStatus.cancel(checkRFidTag)
app = App(title="RFID EM4100 Simple GUI", width=350, height=150, layout="auto")
instructionText = Text(app, text="Click on the text button below\nand scan your RFid tag.")
rfidText = TextBox(app,text="")
rfidStatus = Text(app, text="—")
rfidStatus.repeat(1000, checkRFidTag)
#designBy = Text(app, text="Design by Idris – Cytron Technologies", align="bottom")
app.display()
view
You could use a timer associated with the app to call a fuction shortly after starting up. For example, use:
app.after(1000,setFocus)
to call:
def setFocus():
nameOfTextBox.focus()
The example below sets up two text boxes and two buttons. By commenting out one or other of the lines in setFocus it sets focus to the right hand text box or the cancel button after one second:
from guizero import App, Text, Box, TextBox, PushButton
import sys
app = App(title="Give Focus")
app.width = 500
app.height = 100
paddingHeight = 1
paddingWidth = 10
buttonWidth = 10
topBoxHeight = 100
bottomBoxHeight = 100
app.height = topBoxHeight + bottomBoxHeight
def setFocus():
rightTextBox.focus()
# buttonCancel.focus()
def call_exit():
buttonCancel.text="Exiting"
buttonCancel.enabled=False
app.update()
app.destroy()
sys.exit()
topBox = Box(app, align="top", width= "fill", height = topBoxHeight, border= True)
textFieldBox = Box(topBox, align="top", width= "fill", height= "fill", border= True, layout = "grid")
paddingT00 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,0])
paddingT10 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [1,0])
message = Text(textFieldBox, text="Text Field Box", grid = [2,0])
paddingT01 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,1])
leftTextBox = TextBox(textFieldBox, text="Type here", width = paddingWidth, height = 1, grid = [1,1])
paddingT21 = Text(textFieldBox, text="", width = paddingWidth, height = paddingHeight, grid = [2,1])
rightTextBox = TextBox(textFieldBox, text="...or here", width = paddingWidth, height = 1, grid = [3,1])
bottomBox = Box(app, align="top", width= "fill", height = bottomBoxHeight, border= True)
buttonBox = Box(bottomBox, align="top", width= "fill", height= "fill", border= True, layout = "grid")
paddingB00 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,0])
paddingB10 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [1,0])
message = Text(buttonBox, text="Button Box", grid = [2,0])
paddingB01 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [0,1])
buttonOK = PushButton(buttonBox, text="OK", width = paddingWidth, height = 1, grid = [1,1])
paddingB21 = Text(buttonBox, text="", width = paddingWidth, height = paddingHeight, grid = [2,1])
buttonCancel = PushButton(buttonBox, text="Cancel", command = call_exit, width = paddingWidth, height = 1, grid = [3,1])
app.after(1000,setFocus)
app.display()

DHT22 Temp sensor causing Tkinter GUI to lag

Hi I've been trying to implement a DHT22 temperature and humidity sensor with Tkinter GUI where it updates regularly while using the GUI. This is done on a Raspberry Pi 4 using Python. However, while the numbers are updating correctly, it would cause the GUI freeze momentarily while updating the numbers. I have already tried multithreading, but it unfortunately didn't help. Is there any solution to this problem? Any help is greatly appreciated.
Here's the code:
# Import the required libraries
import RPi.GPIO as GPIO
import spidev
import time
import tkinter
from tkinter import *
import tkinter.font as tkFont
from PIL import ImageTk, Image
# import time
import smbus
import serial
import os
import argparse
import Adafruit_DHT
from threading import Thread
SENSOR = Adafruit_DHT.DHT22
# GPIO4 on the Raspberry Pi
SENSOR_PIN = 4
address = 0b01
ssPin = 8
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 976000
spi.mode = 0b11
#spi.bit_order = msbfirst
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(ssPin,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(26,GPIO.OUT)
GPIO.output(ssPin,GPIO.LOW)
GPIO.output(22,GPIO.HIGH)
GPIO.output(26,GPIO.HIGH)
class App:
def __init__(self, master):
def SendScaleReading(self):
S = scale.get() #retrieve value from slider
if S>0:
S+=155
print(S)
spi.xfer([address ,S]) #write data to slave address
frame = Frame(master)
frame.pack()
scale = tkinter.Scale(root,from_=0,to=100,length=700,bg='black',fg='#0000FF', highlightthickness = 0, bd = 0, command=SendScaleReading) #set parameters of slider
scale.place(relx=0.75, rely=0.05)
#scale.place(relx = 0, rely = 0) # set position of slider
fontstyle = tkFont.Font(family='Arial', size=50) #initialise font
scale['font'] = fontstyle
def PowerFn():
global powerBool
# print(ledBool)
if powerBool:
#print('went to on button')
powerBtn.config(image=On_BtnImg)
powerBtn.image = On_BtnImg
#print("on button configured")
powerLabel.config(text="POWER: ON", fg='#00FF00')
# communicating with arduino
GPIO.output(26,GPIO.LOW)
else:
#print('went to off button')
powerBtn.config(image=Off_BtnImg)
powerBtn.image = Off_BtnImg
#print("off button configured")
powerLabel.config(text="POWER: OFF", fg='#FF0000')
# communicating with arduino
GPIO.output(26,GPIO.HIGH)
powerBool = not powerBool
def DirectionFn():
global directionBool
# print(cbBool)
if directionBool:
#print('went to CbOn button')
directionBtn.config(image = On_BtnImg)
directionBtn.image = On_BtnImg
#print("CbOn button configured")
directionLabel.config(text="FORWARD", fg='#00FF00')
# communicating with arduino
GPIO.output(22,GPIO.HIGH)
else:
#print('went to CbOff button')
directionBtn.config(image = Off_BtnImg)
directionBtn.image = Off_BtnImg
# print("CbOff button configured")
directionLabel.config(text="REVERSE", fg='#FF0000')
# communicating with arduino
GPIO.output(22,GPIO.LOW)
directionBool = not directionBool
def tempsensor():
while True:
print("bruh moment")
h, t = Adafruit_DHT.read_retry(SENSOR, SENSOR_PIN)
print(t)
print(h)
temp = "%.1F" %t
hum = "%.1f" %h
temperature.set(temp+ " *C")
humidity.set(hum+ " %")
time.sleep(1);
root = Tk()
app = App(root)
root.config(bg='black')
#root.attributes('-zoomed', True)
#root.state('fullscreen')
rootWidth = root.winfo_screenwidth()
rootHeight = root.winfo_screenheight()
root.attributes('-zoomed', True)
# Create mini window
#canvas = Canvas(root, bg='black', highlightbackground='white')
#canvas.place(relx=0.1, rely=0.03, relheight=0.51, relwidth=0.505)
temperature = StringVar()
temperature.set("----"+" *C")
humidity = StringVar()
humidity.set("----"+" %")
#root.after(2000, tempsensor)
h, t = Adafruit_DHT.read_retry(SENSOR, SENSOR_PIN)
On_img = Image.open("/home/pi/Downloads/on.png")
Off_img = Image.open("/home/pi/Downloads/off.png")
# Resize the image using resize() method according to the screen height and width
btnWidth = int(rootWidth / 6.4)
print(btnWidth)
infobtnWidth = int(rootHeight / 10)
print(infobtnWidth)
On_resize_img = On_img.resize((btnWidth, btnWidth))
Off_resize_img = Off_img.resize((btnWidth, btnWidth))
On_BtnImg = ImageTk.PhotoImage(On_resize_img)
Off_BtnImg = ImageTk.PhotoImage(Off_resize_img)
normalWidth = 1920 # Width of monitor screen used to write this code
normalHeight = 1080 # Height of monitor screen used to write this code
percentWidth = rootWidth / (normalWidth / 100)
percentHeight = rootHeight / (normalHeight / 100)
scale = ((percentWidth + percentHeight) / 2) / 100
fontsize = int(14 * scale)
fontsize = 50
fontstyle = tkFont.Font(family='Arial', size=fontsize)
titleFontsize = int(50 * scale)
if titleFontsize < 8:
titleFontsize = 8
TitleFontstyle = tkFont.Font(family="Gothic", size=titleFontsize)
## Labels ##
titleLabel = Label(root, text="MAX5487 DigiPot", font=TitleFontstyle, fg="red", bg="black")
titleLabel.place(relx=0.35, rely=0.05)
powerLabel = Label(root, text="POWER: OFF", font=fontstyle, fg='red', bg='black')
powerLabel.place(relx=0.2, rely=0.65, anchor=N)
directionLabel = Label(root, text="FORWARD", font=fontstyle, fg='#00FF00', bg='black')
directionLabel.place(relx=0.5, rely=0.65 , anchor=N)
powerBool = True
# boolean for led button
powerBtn = Button(root, image=Off_BtnImg, bg='black', bd=0, activebackground='black', highlightthickness = 0, command=PowerFn)
powerBtn.place(relx=0.2, rely=0.35, anchor=N)
directionBool = False
directionBtn = Button(root, image=On_BtnImg, bg='black', bd=0, activebackground='black', highlightthickness = 0, command=DirectionFn)
directionBtn.place(relx=0.5, rely=0.35, anchor=N)
templabel = Label(root, textvariable=temperature, font=fontstyle, fg='white', bg='red', highlightthickness = 0)
templabel.place(relx=0.2, rely=0.8, anchor=N)
humidlabel = Label(root, textvariable=humidity, font=fontstyle, fg='white', bg='red', highlightthickness = 0)
humidlabel.place(relx=0.5, rely=0.8, anchor=N)
# Button for closing
exit_button = Button(root, text="Exit", font=fontstyle, fg='white', bg='red', highlightthickness = 0, command=root.destroy)
exit_button.place(relx=0.5, rely=0.9, anchor=N)
background_thread = Thread(target=tempsensor)
background_thread.start()
root.mainloop()

Python program can't handle running exes

My program stops working after successfully running the two exes. here is the code:
from tkinter import *
import os
root = Tk()
root.geometry('350x150')
root.title("hurler")
photo = PhotoImage(file = "Logo_Image.png")
root.iconphoto(False, photo)
entry_text = Label(text = "Number of posts you wish to automate (between 1-12) * ")
entry_text.place(x = 15, y = 10)
num = StringVar()
time_entry = Entry(textvariable = num, width = "10")
time_entry.place(x = 15, y = 40)
def action():
global num
num = num.get()
if num == '1':
os.startfile('.\\hurl\\hurl.exe')
# exit()
if num == '2':
os.startfile('.\\hurl\\hurl.exe')
os.startfile('.\\hurl2\\hurl.exe')
# exit()
num = StringVar()
register = Button(root,text = "Make", width = "10", height = "2", command = action, bg = "lightblue")
register.place(x = 15, y = 70)
root.mainloop()
hurl takes in text entries and then runs a web driver exe after pressing the Post button. Heres a sample block from code from hurl:
from tkinter import *
import os
from time import sleep
root = Tk()
root.geometry('600x600')
root.title("hurl")
photo = PhotoImage(file = "Logo_Image.png")
root.iconphoto(False, photo)
def save_post():
emailE = email_in.get()
file1 = open ("user.txt", "w")
file1.write(emailE)
file1.close()
passE = pass_in.get()
file2 = open ('pass.txt', 'w')
file2.write(passE)
file2.close()
entry1_text = Label(text = "Email * ",)
entry2_text = Label(text = "Password * ",)
entry1_text.place(x = 15, y = 70)
entry2_text.place(x = 15, y = 130)
email_in = StringVar()
pass_in = StringVar()
email_entry = Entry(textvariable = email_in, width = "30")
pass_entry = Entry(textvariable = pass_in, width = "30")
def app():
os.system(".\Auto_Post_With_Photo.exe")
def everything():
save_post()
app()
register = Button(root,text = "Post", width = "10", height = "2", command = everything, bg = "lightblue")
register.place(x = 15, y = 380)
root.mainloop()
I'm hoping I don't need to show the last program to get an answer to the issue. The Issue I'm having is that the program runs perfectly until the button is pressed, and then the hurls exes crash.
But if I click on the two hurl.exe with my mouse and not this 3rd program pressing the post button won't crash.
Any ideas to fix this issue? Also, it's not due to the 'exit()s', it does the same thing with or without them. :)

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.
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()

How can i change image periodically and label values too

I've 2 questions on your code of changing an image periodically. I've run your code and the images are changing perfectly fine, but when im trying to include your patch with mine the images isn't in order and random images are generating. my code is about web-socket program where the rpi is the client and esp32 is the server and the data is coming in sprintf format.
The thing is that I've to take that data and paste on the images I've in my dir.
there are 4 images and each image has 4 different parameters.
My 2nd question is that when the image is change the data should also get change periodically. also can i set the timings of an image like which image should get display first and its data too.
It'd be a great help if you can enlighten me on this.
i'm putting my code below for your reference.
CODE :
import tkinter as Tk
import tkinter as tk
from tkinter import *
import websocket
from PIL import Image, ImageTk
from parse import *
import image
import itertools
import os
import sys
import shutil
import threading
import time
def update_image(dst):
test_image = '/home/pi/Desktop/kvar pix exb/KVAR PIX P1.jpg', '/home/pi/Desktop/kvar pix exb/KVAR PIX P2.jpg', '/home/pi/Desktop/kvar pix exb/KVAR PIX P3.jpg','/home/pi/Desktop/kvar pix exb/KVAR PIX P4.jpg'
for src in itertools.cycle(test_image):
shutil.copy(src, dst)
time.sleep(1) # pause between updates
def refresh_image(canvas,img,image_path,image_id):
try:
pil_img = Image.open(image_path).resize((width_value,height_value), Image.ANTIALIAS)
img = ImageTk.PhotoImage(pil_img)
canvas.itemconfigure(image_id,image=img)
except IOError:
img = None
#repeat every half sec
canvas.after(500,refresh_image,canvas,img,image_path,image_id)
window = tk.Tk()
image_path = 'test.png'
#comparing the incoming data and addr given by the server
comparing_data = ['\x02','45']
#getting values from server
labeltxt_1 = StringVar()
labeltxt_2 = StringVar()
labeltxt_3 = StringVar()
labeltxt_4 = StringVar()
labeltxt_5 = StringVar()
labeltxt_6 = StringVar()
labeltxt_7 = StringVar()
def comm_loop():
global result,labeltxt_1
ws = websocket.WebSocket()
ws.connect("ws://192.168.4.1:7/")
while 1:
result = ws.recv()
incoming_data = result.split(',')
while 1:
if (incoming_data[1] != comparing_data[1]):
print("unauthorised server")
else:
break
print(incoming_data)
labeltxt_1.set(' '+incoming_data[2])
labeltxt_2.set(' '+incoming_data[3])
labeltxt_3.set(' '+incoming_data[4])
labeltxt_4.set(' '+incoming_data[5])
labeltxt_5.set(' '+incoming_data[6])
labeltxt_6.set(' '+incoming_data[7])
labeltxt_7.set(' '+incoming_data[8])
ws.close()
#threading
thread = threading.Thread(target=comm_loop)
thread.daemon = True
thread.start()
#threading
th = threading.Thread(target = update_image, args=(image_path,))
th.daemon = True
th.start()
while not os.path.exists(image_path):
time.sleep(0.1)
width_value = window.winfo_screenwidth()
height_value = window.winfo_screenheight()
window.attributes("-fullscreen", True)
window.config(highlightthickness = 0)
canvas = Canvas(window,width=1920,height=1080)
label_1 = Label(window, textvariable = labeltxt_1, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 600, y = 355)
label_2 = Label(window, textvariable = labeltxt_2, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 640, y = 530)
label_3 = Label(window, textvariable = labeltxt_3, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 850, y = 710)
label_4 = Label(window, textvariable = labeltxt_4, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 730, y = 880)
for i in range(0,0.5):
i=i+1
label_5 = Label(window, textvariable = labeltxt_5, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 600, y = 355)
label_6 = Label(window, textvariable = labeltxt_6, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 640, y = 530)
label_7 = Label(window, textvariable = labeltxt_7, fg = "#FF8000", font = ("Times",78), bg = "#FFFFFF").place(x = 850, y = 710)
img = None
image_id = canvas.create_image(0,0,anchor=NW,image=img)
canvas.pack()
refresh_image(canvas,img,image_path,image_id)
window.mainloop()

Categories