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
  Interaction between Matplotlib window, Python prompt and TKinter window NorbertMoussy 3 486 Mar-17-2024, 09:37 AM
Last Post: deanhystad
  'NoneType' object has no attribute 'get' zunebuggy 8 1,361 Oct-13-2023, 06:39 PM
Last Post: zunebuggy
  [Tkinter] Update label if there are no records in treeview TomasSanchexx 1 930 Aug-20-2023, 04:45 PM
Last Post: menator01
  tkinter AttributeError: 'GUI' object has no attribute pfdjhfuys 3 1,537 May-18-2023, 03:30 PM
Last Post: pfdjhfuys
  PysimpleGUI window update dynamically SamLiu 6 4,002 Apr-05-2023, 02:32 PM
Last Post: SamLiu
  [Kivy] Windows 10: AttributeError: 'WM_PenProvider' object has no attribute 'hwnd' mikepy 1 2,310 Feb-20-2023, 09:26 PM
Last Post: deanhystad
  AttributeError: 'NoneType' object has no attribute 'get' George87 5 15,414 Dec-23-2021, 04:47 AM
Last Post: George87
  [PyQt] AttributeError: 'NoneType' object has no attribute 'text' speedev 9 11,404 Sep-25-2021, 06:14 PM
Last Post: Axel_Erfurt
  update text variable on label with keypress knoxvilles_joker 3 4,900 Apr-17-2021, 11:21 PM
Last Post: knoxvilles_joker
  [Tkinter] AttributeError: '' object has no attribute 'tk' Maryan 2 14,611 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