通过线程向def函数发送变化的变量
问题描述:
我正在制作一个自动温室,通过测量温度,有些事情要像打开一个窗口或控制风扇一样根据值的变化在温度,我使用tkinter在python上创建了这个程序,所以当条件成立时,elif,如果它们是在函数内部def它们发送打印,但是当我运行我的代码时,即使温度值发生变化,我也会将此温度值发送给其他def函数他们使用,所以他们似乎总是使用第一,如果忽略其余条件。我尝试了调试,但是因为我正在使用Beaglebone中的Geany,所以似乎无法找到选项。通过线程向def函数发送变化的变量
#!/usr/bin/python2.7
import thread
import Tkinter as tk
from time import sleep
import Adafruit_BBIO.PWM as PWM
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.ADC as ADC
#PWM.start(channel,duty,freq=1000,polarity=0)
#values for duty are from 0.0 to 100.0 (%)
PWM.start("P8_13",0,50)
GPIO.setup("P8_15",GPIO.OUT)
GPIO.output("P8_15",GPIO.LOW)
GPIO.setup("P8_16",GPIO.OUT)
GPIO.output("P8_16",GPIO.LOW)
PWM.start("P9_14",0,50)
ADC.setup()
def med_temp(close):
adclose=close
while adclose < 1:
raw=ADC.read('P9_33')*1800
t=raw/10
temp1=round(t,0)
tempvar.set(temp1)
sleep(1)
def window_thread(close, value):
gpioclose1=close
temp=value
while gpioclose1<1:
if temp>=30.0 :
#print temp
duty=90
PWM.set_duty_cycle("P9_14",duty)
sleep(.1)
windvar.set('OPEN',)
label11["fg"]='green'
else:
duty=0
PWM.set_duty_cycle("P9_14",duty)
sleep(.1)
windvar.set('CLOSE')
label11["fg"]='red'
def fan1_thread(close,value):
gpioclose=close
temp=value
while gpioclose<1:
if temp<=23.0:
#out
GPIO.output("P8_15", GPIO.LOW)#OUT
GPIO.output("P8_16", GPIO.HIGH)
sleep(.1)
ventvar.set('OUT ')
label6["fg"]='#6c132b'
elif temp>=40.0:
#in
GPIO.output("P8_15", GPIO.HIGH)#IN
GPIO.output("P8_16", GPIO.LOW)
sleep(.1)
ventvar.set('IN ')
label6["fg"]='#5cbdea'
else:
#off
GPIO.output("P8_15", GPIO.LOW)#OFF
GPIO.output("P8_16", GPIO.LOW)
sleep(.1)
ventvar.set('OFF ')
label6["fg"]='red'
def fan2_thread(close,value):
pwmclose=close
temp=value
while pwmclose<1:
if temp<23.0:
duty=100
PWM.set_duty_cycle("P8_13",duty)
sleep(.1)
dutyvar.set(duty)
elif temp<25.0 and temp>=23.0:
duty=50
PWM.set_duty_cycle("P8_13",duty)
sleep(.1)
dutyvar.set(duty)
elif temp>=40.0:
duty=100
PWM.set_duty_cycle("P8_13",duty)
sleep(.1)
dutyvar.set(duty)
else:
duty=0
PWM.set_duty_cycle("P8_13",duty)
sleep(.1)
dutyvar.set(duty)
def salir():
pwmclose = 1
adclose =1
gpioclose =1
gpioclose1=1
PWM.stop("P8_13")
PWM.cleanup()
GPIO.cleanup()
exit()
mainw = tk.Tk()
mainw.title("Greenhouse control")
#contenido
tempvar = tk.DoubleVar()
ventvar = tk.StringVar()
dutyvar = tk.DoubleVar()
windvar = tk.StringVar()
label1 = tk.Label(mainw,text=' Temperature: ', width=len(' Temperature: '),bg='red')
label2 = tk.Label(mainw, textvariable=tempvar, bg='white')
label3 = tk.Label(mainw, text='C', width=len('C'), bg='white')
label4 = tk.Label(mainw, text=' FAN ', width=len(' FAN '),bg='purple')
label5 = tk.Label(mainw, text='Estado: ',width=len('Estate: '))
label6 = tk.Label(mainw, textvariable=ventvar,bg='white')
slider = tk.Scale(mainw, variable = dutyvar,from_=100, to=0)#
label9 = tk.Label(mainw, text=' WINDOW ', width=len(' WINDOW '), bg='purple')
label10 = tk.Label(mainw, text='Estate: ',width=len('State: '))
label11 = tk.Label(mainw, textvariable=windvar, bg='white')
thread.start_new_thread(window_thread,(0,tempvar,))
thread.start_new_thread(med_temp, (0,))
thread.start_new_thread(fan1_thread, (0,tempvar,))
thread.start_new_thread(fan2_thread, (0,tempvar,))
salirButton = tk.Button(mainw, text='EXIT', command=salir,activeforeground='red')
#set layout
label2.grid(row=0, column=1)
label1.grid(row=0, column=0)
label3.grid(row=0, column=2)
label4.grid(row=1,column=0, columnspan=4)
label5.grid(row=2, column=0)
label6.grid(row=2, column=1)
slider.grid(row=2, column=2, columnspan=2)
label9.grid(row=3, column=0, columnspan=4)
label10.grid(row=4, column=0)
label11.grid(row=4, column=1)
salirButton.grid(row=5, column=0, columnspan=4)
mainw.mainloop()
所以我去发送打印温度里面,如果我得到PY_VARO。在这一行 thread.start_new_thread(window_thread,(0,tempvar,)) 我发送到def函数0关闭函数,我发送tempvar是一个双精度。如果我写 thread.start_new_thread(window_thread,(0,tempvar.get))
我得到在打印临时的,如果里面: 绑定的方法DoubleVar.get Tkinter.DoubleVar
,所以我想,如果条件不会被忽略,但是当我启动线程时,我将错误的值发送给def了?什么正确的格式发送给一个函数?
答
Welp,我是通过创建许多线程做错了。我终于让我的温室做我想做的事。这是我的最终代码:
#!/usr/bin/python2.7
import thread
import Tkinter as tk
from time import sleep
import Adafruit_BBIO.PWM as PWM
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.ADC as ADC
#PWM.start(channel,duty,freq=1000,polarity=0)
#values for duty are from 0.0 to 100.0 (%)
#VENTILADOR
PWM.start("P8_13",0,4000)
GPIO.setup("P8_15",GPIO.OUT)
GPIO.output("P8_15",GPIO.LOW)
GPIO.setup("P8_16",GPIO.OUT)
GPIO.output("P8_16",GPIO.LOW)
#VENTANA
PWM.start("P9_14",1,50)#start closed servo
#temperatura
ADC.setup()
def med_temp(close):
adclose=close
while adclose < 1:
raw=ADC.read('P9_33')*1800
t=raw/10
temp=round(t,0)
tempvar.set(temp)
if temp <23:
GPIO.output("P8_15", GPIO.LOW)#OUT
GPIO.output("P8_16", GPIO.HIGH)
PWM.set_duty_cycle("P8_13",100)
PWM.set_duty_cycle("P9_14",1)#closed
sleep(.1)
windvar.set('CLOSE')
label11["fg"]='red'
ventvar.set('OUT ')
label6["fg"]='#6c132b'
dutyvar.set(100)
elif temp >= 23 and temp < 25:
PWM.set_duty_cycle("P8_13",50)
GPIO.output("P8_15", GPIO.LOW)#OUT
GPIO.output("P8_16", GPIO.HIGH)
PWM.set_duty_cycle("P9_14",1)#closed
sleep(.1)
windvar.set('CLOSE')
label11["fg"]='red'
ventvar.set('OUT ')
label6["fg"]='#6c132b'
dutyvar.set(50)
elif temp>=25 and temp<30:
GPIO.output("P8_15", GPIO.LOW)#OFF
GPIO.output("P8_16", GPIO.LOW)
PWM.set_duty_cycle("P8_13",0)
PWM.set_duty_cycle("P9_14",1)#closed
sleep(.1)
windvar.set("CLOSE")
label11["fg"]='red'
ventvar.set('OFF ')
label6["fg"]='red'
dutyvar.set(0)
#print temp
#print'OFF 0% CLOSE'
elif temp>=30 and temp < 35:
GPIO.output("P8_15", GPIO.LOW)#OFF
GPIO.output("P8_16", GPIO.LOW)
PWM.set_duty_cycle("P8_13",0)
PWM.set_duty_cycle("P9_14",5)#opened
sleep(.1)
windvar.set('OPEN')
label11["fg"]='green'
ventvar.set('OFF ')
label6["fg"]='red'
dutyvar.set(0)
print temp
#print'OFF 0% OPEN'
elif temp>=35 and temp < 40:
GPIO.output("P8_15", GPIO.HIGH)#IN
GPIO.output("P8_16", GPIO.LOW)
PWM.set_duty_cycle("P8_13",50)
PWM.set_duty_cycle("P9_14",5)#opened
sleep(.1)
windvar.set('OPEN')
label11["fg"]='green'
ventvar.set('IN ')
label6["fg"]='#5cbdea'
dutyvar.set(50)
print temp
#print'IN 50% OPEN'
else:
GPIO.output("P8_15", GPIO.HIGH)#IN
GPIO.output("P8_16", GPIO.LOW)
PWM.set_duty_cycle("P8_13",100)
PWM.set_duty_cycle("P9_14",5)#opened
sleep(.1)
windvar.set('OPEN')
label11["fg"]='green'
ventvar.set('IN ')
label6["fg"]='#5cbdea'
dutyvar.set(100)
print temp
#print'IN 100% OPEN'
sleep(1)
def salir():
adclose =1
#gpioclose =1
#gpioclose1=1
PWM.stop("P8_13")
PWM.stop("P9_14")
PWM.cleanup()
GPIO.cleanup()
exit()
mainw = tk.Tk()
mainw.title("Control de Invernadero")
#contenido
tempvar = tk.DoubleVar()
ventvar = tk.StringVar()
dutyvar = tk.DoubleVar()
windvar = tk.StringVar()
label1 = tk.Label(mainw,text=' Temperatura: ', width=len(' Temperatura: '),bg='red')
label2 = tk.Label(mainw, textvariable=tempvar, bg='white')
label3 = tk.Label(mainw, text='C', width=len('C'), bg='white')
label4 = tk.Label(mainw, text=' VENTILADOR ', width=len(' VENTILADOR '),bg='purple')
label5 = tk.Label(mainw, text='Estado: ',width=len('Estado: '))
label6 = tk.Label(mainw, textvariable=ventvar,bg='white')
slider = tk.Scale(mainw, variable = dutyvar,from_=0, to=100, orient = tk.HORIZONTAL)#
label9 = tk.Label(mainw, text=' VENTANA ', width=len(' VENTANA '), bg='purple')
label10 = tk.Label(mainw, text='Estado: ',width=len('Estado: '))
label11 = tk.Label(mainw, textvariable=windvar, bg='white')
thread.start_new_thread(med_temp, (0,))
salirButton = tk.Button(mainw, text='SALIR', command=salir,activeforeground='red')
#set layout
label2.grid(row=0, column=1)
label1.grid(row=0, column=0)
label3.grid(row=0, column=2)
label4.grid(row=1,column=0, columnspan=4)
label5.grid(row=2, column=0)
label6.grid(row=2, column=1)
slider.grid(row=2, column=2, columnspan=2)
label9.grid(row=3, column=0, columnspan=4)
label10.grid(row=4, column=0)
label11.grid(row=4, column=1)
salirButton.grid(row=5, column=0, columnspan=4)
mainw.mainloop()
我认为你有错别字temp = valor(value)。此外,函数永不退出,即只在初始启动时执行,因为while变量不会改变,即“while adclose
我得到PY_VARO - Tkinter的StringVar()等都使用get和set方法来访问这些值。 Effbot的页面说明了set()方法http://effbot.org/tkinterbook/variable.htm –
Tkinter和线程不会混合,应该避免。相反,看看使用'后'方法:http://effbot.org/tkinterbook/widget.htm – ebarr