简体   繁体   中英

Python While loop within mainloop causing lag

When I run the code with the while True: loop included within the root.mainloop() it is making my GUI lag heavily and the code does not run as smoothly as I would like. I am wondering how I make my code run smooth and without lag.

for the purpose of this test I have commented out large sections of the code that only work when it is hooked up to my raspberry pi.

Thank you in advance for your help.

import os
import glob
import time
#import RPi.GPIO as GPIO
from datetime import datetime
from tkinter import *

'''
#Set gpio's
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17,GPIO.OUT)#RED
GPIO.setup(22,GPIO.OUT)#GREEN
GPIO.setup(27,GPIO.OUT)#BLUE


#grab temp probe information
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'


# Read temperature from device

def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp():
    lines=read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.1)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000
        #temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c#, temp_f

'''
temp = 18
desiredtemp = 17
deg = u'\xb0'#utf code for degree

#increase button press
def increase():
    global desiredtemp
    desiredtemp += 0.5
    tmpstr.set("%s" % desiredtemp)


#Decrease button press
def decrease():
    global desiredtemp
    desiredtemp -= 0.5
    tmpstr.set("%s" % desiredtemp)




#Tkinter start 
root = Tk()
root.wm_title("Temp") #Name the title bar

#code to add widgets will go here....

#make 3 frames for text and buttons
topFrame = Frame(root)
topFrame.pack(side=TOP)

middleFrame = Frame(root)
middleFrame.pack()

bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)

tmpstr = StringVar(value="%s" % desiredtemp)
crtmpstr = StringVar(value="%s" % temp)

#Set labels
label1 = Label(topFrame, text="Desired Temp = ", fg="black")
label2 = Label(middleFrame, text="Actual Temp = ", fg="black")
label3 = Label(topFrame, textvariable=tmpstr, fg="black")
label4 = Label(middleFrame, textvariable=crtmpstr, fg="black")

#use to put labels on screen
label1.pack(side=LEFT)
label2.pack(side=LEFT)
label3.pack(side=LEFT)
label4.pack(side=LEFT)

#Set buttons
button1 = Button(bottomFrame, text="Increase (0.5"+ deg +"C)", fg="black", command=increase)
button2 = Button(bottomFrame, text="Decrease (0.5"+ deg +"C)", fg="black", command=decrease)

#use to put buttons on screen
button1.pack(side=LEFT)
button2.pack(side=LEFT)


#Tkinter End


# Open file to be logged
'''
file = open("/home/pi/Desktop/Templog.csv", "a")

if os.stat("/home/pi/Desktop/Templog.csv").st_size == 0:
    file.write("Date, Time, TemperatureSensor1\n")

'''


# Continuous print loop
while 1:
    print(temp)
    if(temp<=desiredtemp):
        #GPIO.output(17,GPIO.LOW)
        #GPIO.output(22,GPIO.HIGH)
        temp += 5
        crtmpstr.set("%s" % temp)
    else:
        #GPIO.output(17,GPIO.HIGH)
        #GPIO.output(22,GPIO.LOW)
        temp -=0.5
        crtmpstr.set("%s" % temp)

    #now = datetime.now()
    #file.write(str(now.day)+"-"+str(now.month)+"-"+str(now.year)+","+str(now.hour)+":"+str(now.minute)+":"+str(now.second)+","+str(read_temp())+"\n")
    #file.flush()
    time.sleep(1)
    root.update()



root.mainloop()

Simply use the after method of TK object. This will not impact redrawing and will not require calling any manual update functions, as it defers the execution of that code until the gui thread is not busy.

Split the code to be executed independently into a separate function and pass it to root.after along with a time delay. The first time I used a delay of 0 so it executes immediately. Then at the end of the function call it again, this time passing the value 1000 (milliseconds) as a delay. It will execute repeatedly until you end the tkinter app.

# ... other code here

def gpiotask():

    global temp

    print(temp)
    if(temp <= desiredtemp):
        GPIO.output(17, GPIO.LOW)
        GPIO.output(22, GPIO.HIGH)
        temp += 5 # <- did you mean 0.5 here ?
        crtmpstr.set("%s" % temp)
    else:
        GPIO.output(17, GPIO.HIGH)
        GPIO.output(22, GPIO.LOW)
        temp -= 0.5
        crtmpstr.set("%s" % temp)

    root.after(1000, gpiotask)

root.after(0, gpiotask)
root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM