2017-04-04 50 views
0

當我運行代碼包括while True:循環它使我的GUI嚴重滯後,代碼運行得不像我想的那麼順利。我想知道如何讓我的代碼運行平穩無滯後。Python while循環內主循環造成滯後

爲了這個測試的目的,我已經註釋了大部分的代碼,只有當它連接到我的覆盆子pi時才起作用。

非常感謝您的幫助。

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() 
+0

做你看我掛的問題之前http://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop –

回答

1

只需使用TK對象的after方法。這不會影響重繪,也不需要調用任何手動更新函數,因爲它會延遲執行該代碼,直到gui線程不忙。

將要獨立執行的代碼拆分爲一個單獨的函數,並將其傳遞給root.after以及一段時間延遲。我第一次使用延遲0,所以它立即執行。然後在該函數結束時再次調用它,這次將值1000(毫秒)作爲延遲。它會重複執行,直到你結束tkinter應用程序。

# ... 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() 
+0

該語句爲false:_「after方法...允許您遠離GUI線程執行功能」_。這不是'後'。 ''之後'仍然在同一個線程中運行代碼。所有'後'都是安排工作在稍後時間完成。 –

+0

好的,謝謝@BryanOakley。我猜測它做了什麼tbh。我會從我的答案中刪除。我猜這個名字是有道理的。 –