1

I seem to be unable to destroy buttons which are inside the frame_login or the frame_login itself. And I need that since all three of these objects are useless to me after I click one of the two buttons.

If inside both function login_xtb and login_tradingview_choose I use the lines:

    self.login_xtb_btn.destroy()
    self.login_tradingview_btn.destroy()

I get an error:

AttributeError: 'UI' object has no attribute 'login_xtb_btn'

If instead of those I use:

self.frame_login.destroy()

I get an error:

_tkinter.TclError: bad window path name ".!canvas.!frame"

I have also tried:

        for widgets in self.canvas_main.winfo_children():
        widgets.destroy()

But I get an error:

_tkinter.TclError: bad window path name ".!canvas.!frame"

My code is below:

class UI:
      def __init__(self):
          self.UI_main = tk.Tk()
          width, height = resolution()
          self.canvas_main = tk.Canvas(self.UI_main, height=height, width=width)
          self.canvas_main.pack()

          self.frame_login = Frame(self.canvas_main, bg='#131d47')
          self.frame_login.pack()
          self.frame_login.place(relx=0.5, rely=0.5, anchor=CENTER)

          self.login_font = tkFont.Font(family='Calibri', size=30)

          self.login_xtb_btn = tk.Button(self.frame_login, text='Log in to XTB', width=25, height=2, command=self.login_xtb())
          self.login_xtb_btn['font'] = self.login_font
          self.login_xtb_btn.pack()
          self.login_tradingview_btn = tk.Button(self.frame_login, text='Log in to Tradingview', width=25, height=2, command=self.login_tradingview_choose())
          self.login_tradingview_btn['font'] = self.login_font
          self.login_tradingview_btn.pack()

          self.UI_main.mainloop()

      def login_xtb(self):
          for widgets in self.canvas_main.winfo_children():
                widgets.destroy()
   

          return 'apple'
      def login_tradingview_choose(self):
          for widgets in self.canvas_main.winfo_children():
               widgets.destroy()


          return 'apple'


def resolution():
    user32 = ctypes.windll.user32
    user32.SetProcessDPIAware()
    width, height = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
    return width, height

How do I delete these three atributes properly?

1 Answers1

0

When you are mapping a function to a widget, you don't want to "call" the function by including parentheses. At these two places in your code:

self.login_xtb_btn = tk.Button(self.frame_login, text='Log in to XTB', width=25, 
height=2, command=self.login_xtb())

self.login_tradingview_btn = tk.Button(self.frame_login, text='Log in to 
Tradingview', width=25, height=2, command=self.login_tradingview_choose())

Notice how your command includes the function name and the parentheses. Instead, just include the function name. So your code can be modified the following way:

class UI:
    def __init__(self):
        self.UI_main = tk.Tk()
        width, height = resolution()
        self.canvas_main = tk.Canvas(self.UI_main, height=height, width=width)
        self.canvas_main.pack()

        self.frame_login = Frame(self.canvas_main, bg='#131d47')
        self.frame_login.pack()
        self.frame_login.place(relx=0.5, rely=0.5, anchor=CENTER)

        self.login_font = tkFont.Font(family='Calibri', size=30)

        self.login_xtb_btn = tk.Button(self.frame_login, text='Log in to XTB', 
        width=25, height=2, command=self.login_xtb)
        self.login_xtb_btn['font'] = self.login_font
        self.login_xtb_btn.pack()
        self.login_tradingview_btn = tk.Button(self.frame_login, text='Log in to 
        Tradingview', width=25, height=2, command=self.login_tradingview_choose)
        self.login_tradingview_btn['font'] = self.login_font
        self.login_tradingview_btn.pack()

        self.UI_main.mainloop()

    def login_xtb(self):
        for widgets in self.canvas_main.winfo_children():
            widgets.destroy()
        return 'apple'

    def login_tradingview_choose(self):
        for widgets in self.canvas_main.winfo_children():
            widgets.destroy()
      return 'apple'


def resolution():
    user32 = ctypes.windll.user32
    user32.SetProcessDPIAware()
    width, height = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
    return width, height
  • 1
    Oh, thanks, I don't know how I have missed that I shouldn't use parentheses, seems I have had a major brain lag ;D Thanks – Jakub Szurlej Aug 20 '22 at 15:11