Search code examples
pythonbuttoninterfacettk

Detete witgets in a class in ttkbootstrap


I am working on a scientific calulator in python and there's a button I want to use to change other buttons in the screen (I want the shift button to change sin,cos and tan to arcsin, arccos, arctan).


import tkinter as tk
import ttkbootstrap as ttk
from ttkbootstrap.constants import *


class Master:
    def __init__(self) -> None:
        self.root = ttk.Window(title= "Calculator", themename= "darkly", size=(400,500))
        self.state = True
    
    def print_numbers(self):
        for i, rows in enumerate(self.numbers):
            self.frame_for_the_buttons = ttk.Frame(self.root)
            self.frame_for_the_buttons.pack(fill= BOTH,expand=True)
            for j, buttons in enumerate(rows):
                if buttons in ("shift","**","sqrt","e","π","±","M"):
                    butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (WARNING,LINK))
                    butt.pack(side=LEFT, expand=True, fill=BOTH)
                elif buttons in ("deg","sin","cos","tan","log","ln","(",")"):
                    butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (SUCCESS,LINK))
                    butt.pack(side=LEFT, expand=True, fill=BOTH)
                elif buttons in ("ac","c","%","/","x","-","+","="):
                    butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (INFO,LINK))
                    butt.pack(side=LEFT, expand=True, fill=BOTH)
                else:
                    butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (LIGHT, LINK))
                    butt.pack(side=LEFT, expand=True, fill=BOTH)
    
    def claculate(self, num):
        if num == "shift":
            self.state = not(self.state)
            if self.state:
                self.frame_for_the_buttons.destroy()
                self.numbers = [("shift","deg","sin","cos","tan"),
                                ("**","log","ln","(",")"),
                                ("sqrt","ac","c","%","/"),
                                ("e","7","8","9","x"),
                                ("π","4","5","6","-"),
                                ("±","1","2","3","+"),
                                ("M","0",",",".","=")]
                self.print_numbers()
            else:
                self.frame_for_the_buttons.destroy()
                self.numbers = [("shift","deg","arcsin","arccos","arctan"),
                                ("**","log","ln","(",")"),
                                ("sqrt","ac","c","%","/"),
                                ("e","7","8","9","x"),
                                ("π","4","5","6","-"),
                                ("±","1","2","3","+"),
                                ("M","0",",",".","=")]
                self.print_numbers()
    
    def mainloop(self):
        #Entry for numbers and operations
        self.entry_operation = ttk.Entry(master= self.root, style="dark", font= "Arial 40 bold")
        self.entry_operation.pack(side = TOP, fill= X, expand= True)
        
        #Numbers
        self.numbers = [("shift","deg","sin","cos","tan"),
                        ("**","log","ln","(",")"),
                        ("sqrt","ac","c","%","/"),
                        ("e","7","8","9","x"),
                        ("π","4","5","6","-"),
                        ("±","1","2","3","+"),
                        ("M","0",",",".","=")]
        self.print_numbers()
        self.root.mainloop()        
        
win = Master()
win.mainloop()

I have tryed to use .destry() and .pack_forget() but none of the methods worked... I also wonder if there's a more efficient way to do the task other than deleting all buttons and replacing them with the ones I want even if I only change 3.


Solution

  • I have found a solution, and is to create another frame for the whole thing and destroying that one, for some reason that works and what I came up before didn't...

    import tkinter as tk
    import ttkbootstrap as ttk
    from ttkbootstrap.constants import *
    
    
    class Master:
        def __init__(self) -> None:
            self.root = ttk.Window(title= "Calculator", themename= "darkly", size=(400,500))
            self.state = True
        
        def print_numbers(self):
            self.frame_for_ev = ttk.Frame(self.root)
            self.frame_for_ev.pack(fill= BOTH,expand=True)
            for i, rows in enumerate(self.numbers):
                self.frame_for_the_buttons = ttk.Frame(self.frame_for_ev)
                self.frame_for_the_buttons.pack(fill= BOTH,expand=True)
                for j, buttons in enumerate(rows):
                    if buttons in ("shift","**","sqrt","e","π","±","M"):
                        butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (WARNING,LINK))
                        butt.pack(side=LEFT, expand=True, fill=BOTH)
                    elif buttons in ("deg","sin","cos","tan","log","ln","(",")"):
                        butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (SUCCESS,LINK))
                        butt.pack(side=LEFT, expand=True, fill=BOTH)
                    elif buttons in ("ac","c","%","/","x","-","+","="):
                        butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (INFO,LINK))
                        butt.pack(side=LEFT, expand=True, fill=BOTH)
                    else:
                        butt = ttk.Button(master= self.frame_for_the_buttons, text=buttons, command= lambda vl=self.numbers[i][j]: self.claculate(vl), style= (LIGHT, LINK))
                        butt.pack(side=LEFT, expand=True, fill=BOTH)
        
        def claculate(self, num):
            if num == "shift":
                self.state = not(self.state)
                if self.state:
                    self.frame_for_ev.destroy()
                    self.numbers = [("shift","deg","sin","cos","tan"),
                                    ("**","log","ln","(",")"),
                                    ("sqrt","ac","c","%","/"),
                                    ("e","7","8","9","x"),
                                    ("π","4","5","6","-"),
                                    ("±","1","2","3","+"),
                                    ("M","0",",",".","=")]
                    self.print_numbers()
                else:
                    self.frame_for_ev.destroy()
                    self.numbers = [("shift","deg","arcsin","arccos","arctan"),
                                    ("**","log","ln","(",")"),
                                    ("sqrt","ac","c","%","/"),
                                    ("e","7","8","9","x"),
                                    ("π","4","5","6","-"),
                                    ("±","1","2","3","+"),
                                    ("M","0",",",".","=")]
                    self.print_numbers()
        
        def mainloop(self):
            #Entry for numbers and operations
            self.entry_operation = ttk.Entry(master= self.root, style="dark", font= "Arial 40 bold")
            self.entry_operation.pack(side = TOP, fill= X, expand= True)
            
            #Numbers
            self.numbers = [("shift","deg","sin","cos","tan"),
                            ("**","log","ln","(",")"),
                            ("sqrt","ac","c","%","/"),
                            ("e","7","8","9","x"),
                            ("π","4","5","6","-"),
                            ("±","1","2","3","+"),
                            ("M","0",",",".","=")]
            self.print_numbers()
            self.root.mainloop()        
            
    win = Master()
    win.mainloop()