Python Forum
[Tkinter] Can't update label in new tk window, object has no attribute
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Can't update label in new tk window, object has no attribute
#1
Hi, I have this code but i get the error "object has no attribute".

from tkinter import *

root = Tk()

root.geometry("300x300")

count = 20

pop_label = None

def ACdriver(option):
#	pop.destroy()
	global count
	if option == "UP":
		count = count + 1
	else:
		count = count - 1
	my_label.config(text=count)
	pop_label.config(text=count)

def ACwindowdriver():
	global pop
	pop = Toplevel(root)
	pop.title("My Popup")
	pop.geometry("150x200+00+00")
	pop.overrideredirect(True) #Borderless
	pop.config(bg="black")


	pop_label = Label(pop, bg="green", fg="white", font=("helvetica", 12))
	pop_label.config(text=count)
	pop_label.grid(row=1, column=0, pady=10)


	my_frame = Frame(pop, bg="black")
	my_frame.grid(row=1, column=1, pady=10)

	heatdriver = Button(my_frame, command=lambda: ACdriver("UP"), bg="black")
	heatdriver.grid(row=2, column=2, pady=10)

	colddriver = Button(my_frame, command=lambda: ACdriver("DOWN"), bg="black")
	colddriver.grid(row=3, column=2, pady=10)

def destroy():
	pop.destroy()


destroy_button = Button(root, text="destroy", command=destroy)
destroy_button.place(x=1, y=1)

ACdriver_button = Button(root, text="ACwindowdriver", command=ACwindowdriver)
ACdriver_button.pack(pady=50)

my_label = Label(root, text="")
my_label.pack(pady=20)



root.mainloop()
I am trying to update the number inside the new tk window called "pop" but the number only updates after i press "destroy" and "ACwindowdriver" again. When i press one button inside the window pop i get the error "'NoneType' object has no attribute 'config'".

Thankfull for all help.

Kind regards
Tom

Attached Files

Thumbnail(s)
       
Reply
#2
The short answer is the pop_label only exists locally to ACwindowdriver
using global in GUI code is not ideal, I prefer to code GUI using classes.

Note: see Namespace flooding with * imports

The code rewritten answer, using classes and an IntVar
import tkinter as tk


class AcWindowDriver(tk.Toplevel):
    def __init__(self, count, *args, **kwargs):
        super().__init__(*args, *kwargs)
        self.title("My Popup")
        self.geometry("150x200+00+00")
        self.overrideredirect(True)  # Borderless
        self.config(bg="black")
        self.count = count
        pop_label = tk.Label(
            self, bg="green", fg="white", font=("helvetica", 12), textvariable=count
        )
        pop_label.config(text=count)
        pop_label.grid(row=1, column=0, pady=10)
        my_frame = tk.Frame(self, bg="black")
        my_frame.grid(row=1, column=1, pady=10)
        heatdriver_btn = tk.Button(
            my_frame, command=self._on_heatdriver_btn, bg="black"
        )
        heatdriver_btn.grid(row=2, column=2, pady=10)
        colddriver_btn = tk.Button(
            my_frame, command=self._on_colddriver_btn, bg="black"
        )
        colddriver_btn.grid(row=3, column=2, pady=10)

    def _on_heatdriver_btn(self):
        current_count = self.count.get()
        self.count.set(current_count + 1)

    def _on_colddriver_btn(self):
        current_count = self.count.get()
        self.count.set(current_count - 1)


class MainFrame(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, *kwargs)
        self.count = tk.IntVar(self, 20)
        self.ac_window_driver = None
        destroy_btn = tk.Button(self, text="destroy", command=self._on_destroy_btn)
        destroy_btn.place(x=1, y=1)
        ac_driver_btn = tk.Button(
            self, text="ACwindowdriver", command=self._on_ac_driver_btn
        )
        ac_driver_btn.pack(pady=50)
        my_label = tk.Label(self, textvariable=self.count)
        my_label.pack(pady=20)

    def _on_destroy_btn(self):
        if not self.ac_window_driver:
            return
        self.ac_window_driver.destroy()
        self.ac_window_driver = None

    def _on_ac_driver_btn(self):
        if self.ac_window_driver:
            return
        self.ac_window_driver = AcWindowDriver(self.count, self)


def main():
    app = tk.Tk()
    app.geometry("300x300")
    main_frame = MainFrame(app)
    main_frame.pack()
    app.mainloop()


if __name__ == "__main__":
    main()
tompranks likes this post
Reply
#3
You could make pop_label a global
def ACwindowdriver():
    global pop, pop_label
but it would be far better to make it an attribute of the class.

Actually, I wouldn't expose the labels at al.I would instead create a tkinter.IntVariable, and use this to set the text of the labels.
import tkinter as tk

class PopupWindow(tk.Toplevel):
    def __init__(self, parent, count):
        super().__init__(parent, bg="black")
        self.overrideredirect(True)
        self.count = count
 
        tk.Label(
            self,
            textvariable=count,
            bg="green",
            fg="white",
            font=("helvetica", 12),
            width=3).pack(padx=5, pady=5)
 
        tk.Button(
            self,
            text=" Up ",
            command=lambda: self.increment(1),
            bg="black",
            fg="green").pack(padx=5, pady=5)
 
        tk.Button(
            self,
            text="Down",
            command=lambda: self.increment(-1),
            bg="black",
            fg="green").pack(padx=5, pady=5)

    def increment(self, amount):
        self.count.set(self.count.get() + amount)


class RootWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Root Window")
        self.popups = []
        self.count = tk.IntVar(self, 20)

        tk.Label(self, textvariable=self.count, width=5) \
            .pack(padx=5, pady=5, side=tk.LEFT)
 
        tk.Button(self, text="Destroy All Popups", command=self.destroy_popups) \
            .pack(padx=5, pady=5, side=tk.LEFT)

        tk.Button(self, text="Create New Popup", command=self.popup) \
            .pack(padx=5, pady=5, side=tk.LEFT)


    def popup(self):
        """Create a popup window"""
        id = len(self.popups)
        popup = PopupWindow(self, self.count")
        self.popups.append(popup)
        x = (id % 5) * 120
        y = (id // 5) * 120
        popup.geometry(f"{120}x{120}+{x}+{y}")

    def destroy_popups(self):
        """Destroy all the popup windows"""
        for pop in self.popups:
            pop.destroy()
        self.popups = []

RootWindow().mainloop()
tompranks likes this post
Reply
#4
Both works perfectly, thank you very much for all your help.

Cheers!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  update text variable on label with keypress knoxvilles_joker 5 5,248 Yesterday, 02:09 PM
Last Post: menator01
  Interaction between Matplotlib window, Python prompt and TKinter window NorbertMoussy 3 854 Mar-17-2024, 09:37 AM
Last Post: deanhystad
  'NoneType' object has no attribute 'get' zunebuggy 8 1,743 Oct-13-2023, 06:39 PM
Last Post: zunebuggy
  [Tkinter] Update label if there are no records in treeview TomasSanchexx 1 1,034 Aug-20-2023, 04:45 PM
Last Post: menator01
  tkinter AttributeError: 'GUI' object has no attribute pfdjhfuys 3 1,791 May-18-2023, 03:30 PM
Last Post: pfdjhfuys
  PysimpleGUI window update dynamically SamLiu 6 4,252 Apr-05-2023, 02:32 PM
Last Post: SamLiu
  [Kivy] Windows 10: AttributeError: 'WM_PenProvider' object has no attribute 'hwnd' mikepy 1 2,503 Feb-20-2023, 09:26 PM
Last Post: deanhystad
  AttributeError: 'NoneType' object has no attribute 'get' George87 5 15,917 Dec-23-2021, 04:47 AM
Last Post: George87
  [PyQt] AttributeError: 'NoneType' object has no attribute 'text' speedev 9 11,753 Sep-25-2021, 06:14 PM
Last Post: Axel_Erfurt
  [Tkinter] AttributeError: '' object has no attribute 'tk' Maryan 2 15,028 Oct-29-2020, 11:57 PM
Last Post: Maryan

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020