Why can I not access any variables that I create in this class? I get Control has no attribute setTemp
whenever I try to access it. If I declare it outside __init__
I also get an error. For whatever reason, I can't grasp how to properly declare variables in a Python class, then later use them in methods.
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from vivTimer import *
import RPi.GPIO as GPO
import threading
import time
import board
import adafruit_dht
dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False)
class Control(object):
setHumid = 95
timer = 5000
def __init__(self, master):
setTemp = StringVar()
setTemp.set('85')
#set default max temp and humidity
master.title('Vivarium Control')
master.resizable(False, False)
master.configure(background = '#e6e6e6')
self.style = ttk.Style()
self.style.configure('TFrame', background = '#e6e6e6')
self.style.configure('TButton', background = '#e1d8b9')
self.style.configure('TLabel', background = '#e6e6e6', font = ('Arial', 11))
self.style.configure('Header.TLabel', font = ('Arial', 18, 'bold'))
self.frame_header = ttk.Frame(master)
self.frame_header.pack()
self.logo = PhotoImage(file = '115500-200.png')
ttk.Label(self.frame_header, image = self.logo).grid(row = 0, column = 0, rowspan = 2)
ttk.Label(self.frame_header, text = 'Vivarium Controller', style = 'Header.TLabel').grid(row = 0, column = 1)
ttk.Label(self.frame_header, wraplength = 300,
text = ("Temperature and Humidity control. "
"Enter maximums for both humidity and temperature.")).grid(row = 1, column = 1, padx = 5, sticky = 'nw')
self.frame_content = ttk.Frame(master)
self.frame_content.pack()
ttk.Label(self.frame_content, text = 'Maximum Temp:').grid(row = 0, column = 0, padx = 5, sticky = 'sw')
ttk.Label(self.frame_content, text = 'Maximum Humidity:').grid(row = 0, column = 1, padx = 5, sticky = 'sw')
self.setTempL = Label(self.frame_content, textvariable = setTemp).grid(row = 0, column = 3, padx = 5, sticky = 'sw')
ttk.Label(self.frame_content, text = 'Current Humidity:' str(self.setHumid)).grid(row = 0, column = 4, padx = 5, sticky = 'sw')
self.entry_temp = ttk.Entry(self.frame_content, textvariable = setTemp, width = 10, font = ('Arial', 10))
self.entry_humid = ttk.Entry(self.frame_content, width = 10, font = ('Arial', 10))
self.entry_temp.grid(row = 1, column = 0, padx = 5)
self.entry_humid.grid(row = 1, column = 1, padx = 5)
ttk.Button(self.frame_content, text = 'Save',
command = self.save).grid(row = 4, column = 0, padx = 5, pady = 5, sticky = 'e')
def updateLabels(self):
print('blah')
def createTimer(root):
print('timer 1 sec')
readTemp = False
while readTemp == False:
try:
# Print the values to the serial port
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) 32
humidity = dhtDevice.humidity
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)
readTemp = True
if(temperature_f > int(Control.setTemp.get())):
print('fan on')
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
dhtDevice.exit()
raise error
time.sleep(2.0)
print(Control.timer)
root.after(Control.timer, Control.createTimer, root)
#t2 = threading.Thread(target=VivTimer.startTimer(), args=(10,))
#t2.start()
def save(self):
tempT = self.entry_temp.get()
self.setTemp = tempT
print(self.setTemp)
self.setHumid = self.entry_humid.get()
Control.updateLabels(self)
print('Temp: {}'.format(self.entry_temp.get()))
print('Humidity: {}'.format(self.entry_humid.get()))
self.clear()
messagebox.showinfo(title = 'Vivarium Control', message = 'Conditions saved!')
def clear(self):
self.entry_temp.delete(0, 'end')
self.entry_humid.delete(0, 'end')
def main():
root = Tk()
control = Control(root)
root.after(1000, Control.createTimer, root)
root.mainloop()
if __name__ == "__main__": main()
CodePudding user response:
I think the following modified version of your code will work much better if you undo all the places I commented out your code (and usually put in a replacement below it). This was necessary to make it possible to run the code at all for testing since I don't have your hardware (or the one image file).
You will need to undo them to try it with your hardware.
The two most significant changes I made were turning setTemp
into a class instance attribute and modifying createTimer()
to make it a proper class method.
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
#from vivTimer import *
#import RPi.GPIO as GPO
import time
#import board
#import adafruit_dht
#
#dhtDevice = adafruit_dht.DHT22(board.D4, use_pulseio=False)
class Control(object):
setHumid = 95
timer = 5000
def __init__(self, master):
self.setTemp = StringVar()
self.setTemp.set('85')
#set default max temp and humidity
master.title('Vivarium Control')
master.resizable(False, False)
master.configure(background = '#e6e6e6')
self.style = ttk.Style()
self.style.configure('TFrame', background = '#e6e6e6')
self.style.configure('TButton', background = '#e1d8b9')
self.style.configure('TLabel', background = '#e6e6e6', font = ('Arial', 11))
self.style.configure('Header.TLabel', font = ('Arial', 18, 'bold'))
self.frame_header = ttk.Frame(master)
self.frame_header.pack()
# self.logo = PhotoImage(file = '115500-200.png')
self.logo = PhotoImage(file = '8-ball.png')
ttk.Label(self.frame_header, image = self.logo).grid(row = 0, column = 0, rowspan = 2)
ttk.Label(self.frame_header, text = 'Vivarium Controller', style = 'Header.TLabel').grid(row = 0, column = 1)
ttk.Label(self.frame_header, wraplength = 300,
text = ("Temperature and Humidity control. "
"Enter maximums for both humidity and temperature.")).grid(row = 1, column = 1, padx = 5, sticky = 'nw')
self.frame_content = ttk.Frame(master)
self.frame_content.pack()
ttk.Label(self.frame_content, text = 'Maximum Temp:').grid(row = 0, column = 0, padx = 5, sticky = 'sw')
ttk.Label(self.frame_content, text = 'Maximum Humidity:').grid(row = 0, column = 1, padx = 5, sticky = 'sw')
self.setTempL = Label(self.frame_content, textvariable=self.setTemp).grid(row = 0, column = 3, padx = 5, sticky = 'sw')
ttk.Label(self.frame_content, text = 'Current Humidity:' str(self.setHumid)).grid(row = 0, column = 4, padx = 5, sticky = 'sw')
self.entry_temp = ttk.Entry(self.frame_content, textvariable=self.setTemp, width = 10, font = ('Arial', 10))
self.entry_humid = ttk.Entry(self.frame_content, width = 10, font = ('Arial', 10))
self.entry_temp.grid(row = 1, column = 0, padx = 5)
self.entry_humid.grid(row = 1, column = 1, padx = 5)
ttk.Button(self.frame_content, text = 'Save',
command = self.save).grid(row = 4, column = 0, padx = 5, pady = 5, sticky = 'e')
def updateLabels(self):
print('blah')
def createTimer(self, root):
print('timer 1 sec')
readTemp = False
while readTemp == False:
try:
# Print the values to the serial port
# temperature_c = dhtDevice.temperature
temperature_c = 30
temperature_f = temperature_c * (9 / 5) 32
# humidity = dhtDevice.humidity
humidity = 20
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)
readTemp = True
if(temperature_f > int(self.setTemp.get())):
print('fan on')
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
# dhtDevice.exit()
raise error
time.sleep(2.0)
print(Control.timer)
root.after(Control.timer, self.createTimer, root)
def save(self):
tempT = self.entry_temp.get()
self.setTemp = tempT
print(self.setTemp)
self.setHumid = self.entry_humid.get()
Control.updateLabels(self)
print('Temp: {}'.format(self.entry_temp.get()))
print('Humidity: {}'.format(self.entry_humid.get()))
self.clear()
messagebox.showinfo(title = 'Vivarium Control', message = 'Conditions saved!')
def clear(self):
self.entry_temp.delete(0, 'end')
self.entry_humid.delete(0, 'end')
def main():
root = Tk()
control = Control(root)
root.after(1000, control.createTimer, root)
root.mainloop()
if __name__ == "__main__":
main()