1

I implemented the following code in python to manipulate an own property (here button.text) of the pressed button. When executing the code I get the following error: "AttributeError: 'Gui' object has no attribute 'button'". Important for my example is, that the button is part of the class and created in its init. Other working examples with a global defined button I found and got running.

#!/usr/bin/python3
# -*- coding: iso-8859-1 -*-

import tkinter
from tkinter import *
from tkinter import ttk

class Gui:
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)
        self.frame.pack(fill='both', side='top', expand='True')

        self.button = Button(master=self.frame, 
                                    text='connect', 
                                    height=20, 
                                    width=80, 
                                    padx=1, 
                                    pady=1, 
                                    command=self.connect_disconnct(),                            
                                    compound=LEFT)                                                  
        self.button.grid(row=0, column=0, padx=5, pady=5, sticky='ew')
        mainloop()

    def connect_disconnct(self):
        if  self.button.test == connect:
            print("Button pressed -> connect")
            self.button.text = "disconnect"
        else:
            print("Button pressed -> disconnect")
            self.button.text = "connect"

if __name__ == '__main__':
  form = Tk()                                                                                       
  Gui(form)
  form.mainloop()

How the own button element can be passed to the callback function so for example the text of the calling object can be changed in the callback function?

Stani
  • 35
  • 5

2 Answers2

2

Remove the () in this line.

command=self.connect_disconnct(),

You want to hand the button a function to call. The () calls the function, executing it before the attribute self.button is set. Even if there were no reference to self.button in the method you would be handing Button the return value of the method, which in this case is None.

There are some additional things wrong with this code. To get the button text, you need to do this self.button['text'] == 'connect'.

Additionally, you cannot set the text in this way. You need to use the configure() method.

self.button.configure(text="disconnect")

Also, you have one too many calls to mainloop().

Full code:

import tkinter
from tkinter import *
from tkinter import ttk

class Gui:
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)
        self.frame.pack(fill='both', side='top', expand='True')

        self.button = Button(master=self.frame, 
                                    text='connect', 
                                    height=20, 
                                    width=80, 
                                    padx=1, 
                                    pady=1, 
                                    command=self.connect_disconnct,                            
                                    compound=LEFT)                                                  
        self.button.grid(row=0, column=0, padx=5, pady=5, sticky='ew')

    def connect_disconnct(self):
        if self.button['text'] =='connect':
            print("Button pressed -> connect")
            self.button.configure(text="disconnect")
        else:
            print("Button pressed -> disconnect")
            self.button.configure(text="connect")

if __name__ == '__main__':
    form = Tk()                                                                                       
    Gui(form)
    form.mainloop()
Axe319
  • 4,255
  • 3
  • 15
  • 31
2

In addition to @Axe319 answer there is a few things:

You are using the wrong syntax to change the button text, the correct syntax is:

self.button.config(text = "disconnect")

As for getting text from the button:

self.button['text'] == 'connect':

Finally there is a spelling error:

self.button.test == connect:
#             x
figbeam
  • 7,001
  • 2
  • 12
  • 18