What might be causing 'type object 'MainFrame' has no attribute 'MainTemp_meter1'' error in my Python GUI program

24 Views Asked by At

I'm working on a code to update my temperature sensor together with a timer and translate this into the gauges on my Gui. the problem is somewhere in the updater code since that is the only code that creates error codes to be more precise this error code: "type object 'MainFrame' has no attribute 'MainTemp_meter1'".

i tried different codes and code styles to get the updater to work but none of then worked so far. Now with the latest one i can atleast keep the Gui running but i can't update anything yet. [imports used]

import tkinter as tk
import customtkinter as ctk
import threading
from tkdial import Meter
from PIL import Image
import datetime as dt
from random import *
import threading

#references to other .py files
import timers
import relays
import sensors
import logs
import time

[updater code]

def update_readings(self):
            try:
                while True:
                    # Update temperature reading 
                    temp_reading_top = sensors.sensor.read_temperature()
                    humid_reading_top = sensors.sensor.read_humidity()
                    MainFrame.MainTemp_meter1.set(temp_reading_top)
                    DiagFrame.temp_meter1.set(temp_reading_top)
                    DiagFrame.humid_meter1.set(humid_reading_top)

                    # Update current date and time
                    date = dt.datetime.now()
                    MainFrame.label_timedate.configure(text=f"{date:%A, %B %d, %Y, %H:%M}")

                    # Update timer label 
                    timer_reading = self.timer_frame.timer10.read_current()
                    formatted_time = timers.Timer.format_time(timer_reading)  # Call format_time from timers.Timer
                    self.timer_frame.time_var.set(formatted_time)

                    print('updated')

                    # Update the GUI
                    MainFrame.update_idletasks()
                    DiagFrame.update_idletasks()
                    TimerFrame.update_idletasks()
                    # Delay for a certain period (e.g., 1 second)
                    time.sleep(1)
            except Exception as e:
                print("Update error:", str(e))
    # Create and start a separate thread for the update loop
    update_thread = threading.Thread(target=update_readings, daemon=True)
    update_thread.start()

up until now i was expecting to get the updater online and make my code work so i can monitor different situations as i like. Some examples of the use are for measuring the temperature inside or outside together with the humidity and put that in a log so i can see what the temperature was around 3 in the morning.

[code MainFrame]

class MainFrame(ctk.CTkFrame):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self.MainTemp_meter1 = tk.StringVar()
        # Code for temperature gauges...
        #temp_reading_top = sensors.sensor.read_temperature()
        #temp_reading_bottom = sensors.sensor.read_temperature()

        # Code for humidity gauges...
        #humid_reading_top = sensors.read_humidity()
        #humid_reading_bottom = sensors.read_humidity()

        date = dt.datetime.now()
        # create label to display
        self.label_timedate = ctk.CTkLabel(self, text=f"{date:%A, %B %d, %Y, %H:%M}")
        self.label_timedate.grid(row=0, column=0, pady=10)

        self.grid_columnconfigure(2, weight=1)
        # add widgets onto the frame, for example:
        self.label = ctk.CTkLabel(self, text="Status")
        self.label.grid(row=1, column=0, padx=10)

        self.MainTemp_meter1 = Meter(self, radius=200, start=0, end=70, border_width=0, fg="#242424", bg="#242424",
               text_color="white", start_angle=270, end_angle=-270,
               text_font="DS-Digital 12", scale_color="white", needle_color="red", text=" \N{DEGREE SIGN}C")
        self.MainTemp_meter1.set_mark(50, 70) # set red marking from 140 to 160
        self.MainTemp_meter1.grid(row=1, column=3, padx=10, pady=10, rowspan=5)
        self.MainTemp_meter1.set(temp_reading_top)

        self.label3 = ctk.CTkLabel(self, text="Temperature")
        self.label3.grid(row=0, column=3, padx=10)

        #self.meter2 = Meter(self, radius=200, start=0, end=70, border_width=0, fg="#242424", bg="#242424",
               #text_color="white", start_angle=270, end_angle=-270,
               #text_font="DS-Digital 12", scale_color="white", needle_color="red", text=" \N{DEGREE SIGN}C")
        #self.meter2.set_mark(50, 70) # set red marking from 140 to 160
        #self.meter2.grid(row=6, column=3, padx=10, pady=10, rowspan=5)
        #self.meter2.set(temp_reading_bottom)
        
        self.label_t1 = ctk.CTkLabel(self, text="Timer 1: ")
        self.label_t1.grid(row=8, column=0, padx=10)

        self.progressbar_t1 = ctk.CTkProgressBar(self)
        self.progressbar_t1.grid(row=8, column=1, padx=(0, 10), pady=(10, 10), sticky="ew")

        self.label_t2 = ctk.CTkLabel(self, text="Timer 2: ")
        self.label_t2.grid(row=9, column=0, padx=10)

        self.progressbar_t2 = ctk.CTkProgressBar(self)
        self.progressbar_t2.grid(row=9, column=1, padx=(0, 10), pady=(10, 10), sticky="ew")

        self.label_t3 = ctk.CTkLabel(self, text="Timer 3: ")
        self.label_t3.grid(row=10, column=0, padx=10)

        self.progressbar_t3 = ctk.CTkProgressBar(self)
        self.progressbar_t3.grid(row=10, column=1, padx=(0, 10), pady=(10, 10), sticky="ew")
        
        self.img_sun = ctk.CTkImage(light_image=Image.open("sun.png"),
                                  dark_image=Image.open("sun.png"),
                                  size=(150, 150))
        self.label_sun = ctk.CTkLabel(self, text="", image=self.img_sun)
        self.label_sun.grid(row=2, column=0, padx=(10, 10), pady=(10, 10), sticky="ew")

        if temp_reading_top > 50:
            self.label2 = ctk.CTkLabel(self, text="warning: temperature exceeded")
            self.label2.grid(row=0, column=1, padx=20)
            self.img_cross = ctk.CTkImage(light_image=Image.open("cross.png"),
                                  dark_image=Image.open("cross.png"),
                                  size=(150, 150))
            self.label_cross = ctk.CTkLabel(self, text="", image=self.img_cross)
            self.label_cross.grid(row=1, column=1, padx=(20, 10), pady=(10, 10), sticky="ew")
        
        updater.update_readings(self)
0

There are 0 best solutions below