Search code examples
pythonuser-interfacetkinterpython-3.7chemistry

How can I make it so that when a button is clicked in Tkinter, any and all labels currently displayed on the screen are replaced with the new label?


So I am working on an interactive periodic table project in Python, and am using Tkinter. I have buttons on it that, when clicked, provide info about the element named on the button. It outputs this as a label, and automatically goes away after 5.5 seconds. There is one thing I need to have done, but cannot seem to find a solution for:

I need a setting so that only one label can be displayed at a time. Currently, if I click the same or different buttons multiple times, the labels stack up on each other. I want there to only be one label, so if a new button is clicked, that label will replace the other.

This is the main code, that includes all the Tkinter stuff. I will also include at the bottom the other file I made with all the periodic table library stuff.

from elementsymbols import *
from tkinter import *


def callback_h():
    labelh = Label(root, text="Element name: " + str(h.name) + "\n" + "Element symbol: " + str(h.symbol) + "\n" + "Atomic mass: " + str(h.atomic_weight) + "\n" + "Atomic number: " + str(h.atomic_number))
    labelh.pack()
    labelh.after(5500, lambda: labelh.config(text=''))


def callback_he():
    labelhe = Label(root, text="Element name: " + str(he.name) + "\n" + "Element symbol: " + str(he.symbol) + "\n" + "Atomic mass: " + str(he.atomic_weight) + "\n" + "Atomic number: " + str(he.atomic_number))
    labelhe.pack()
    labelhe.after(5500, lambda: labelhe.config(text=''))


def callback_li():
    labelli = Label(root, text="Element name: " + str(li.name) + "\n" + "Element symbol: " + str(li.symbol) + "\n" + "Atomic mass: " + str(li.atomic_weight) + "\n" + "Atomic number: " + str(li.atomic_number))
    labelli.pack()
    labelli.after(5500, lambda: labelli.config(text=''))


class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.init_window()

    # Creation of init_window
    def init_window(self):
        # changing the title of our master widget
        self.master.title("Interactive Periodic Table v1")
        # allowing the widget to take the full space of the root window
        self.pack(fill=BOTH, expand=1)
        # creating a button instance
        hbutton = Button(self, text="Hydrogen - H", command=callback_h)
        # placing the button on my window
        hbutton.place(x=0, y=0)
        # all other elements
        hebutton = Button(self, text="Helium - He", command=callback_he)
        hebutton.place(x=100, y=0)

        libutton = Button(self, text="Lithium - Li", command=callback_li)
        libutton.place(x=190, y=0)


root = Tk()
# size of the window
root.geometry("600x500")
app = Window(root)
root.mainloop()

That is the main code, here is where it is getting the periodic table info from:

from mendeleev import element
h = element('H')
he = element('He')
li = element('Li')
be = element('Be')
b = element('B')
c = element('C')
n = element('N')
o = element('O')
f = element('F')
ne = element('Ne')
na = element('Na')
mg = element('Mg')
al = element('Al')
si = element('Si')
p = element('P')
s = element('S')
cl = element('Cl')
ar = element('Ar')
k = element('K')
ca = element('Ca')
sc = element('Sc')
ti = element('Ti')
v = element('V')
cr = element('Cr')

Any and all help related to this would be appreciated, however actual code examples pertaining to my code would be extremely helpful and greatly appreciated.


Solution

  • What needs to be done is that root=Tk() needs to be moved to the top, then the labels need to be created outside. The final code is shown below.

    from elementsymbols import *
    from tkinter import *
    
    root = Tk()
    
    labelh = Label()
    labelhe = Label()
    labelli = Label()
    labelbe = Label()
    
    
    def remove():
        labelh.config(text='')
        labelhe.config(text='')
        labelli.config(text='')
        labelbe.config(text='')
    
    
    def callback_h():
        remove()
        labelh.config(text="Element name: " + str(h.name) + "\n" + "Element symbol: " + str(h.symbol) + "\n" + "Atomic mass: " + str(h.atomic_weight) + "\n" + "Atomic number: " + str(h.atomic_number))
        labelh.after(5500, lambda: labelh.config(text=''))
        labelh.pack()
    
    
    def callback_he():
        remove()
        labelhe.config(text="Element name: " + str(he.name) + "\n" + "Element symbol: " + str(he.symbol) + "\n" + "Atomic mass: " + str(he.atomic_weight) + "\n" + "Atomic number: " + str(he.atomic_number))
        labelhe.after(5500, lambda: labelhe.config(text=''))
        labelhe.pack()
    
    
    def callback_li():
        remove()
        labelli.config(text="Element name: " + str(li.name) + "\n" + "Element symbol: " + str(li.symbol) + "\n" + "Atomic mass: " + str(he.atomic_weight) + "\n" + "Atomic number: " + str(li.atomic_number))
        labelli.after(5500, lambda: labelli.config(text=''))
        labelli.pack()
    
    
    def callback_be():
        remove()
        labelbe.config(text="Element name: " + str(be.name) + "\n" + "Element symbol: " + str(be.symbol) + "\n" + "Atomic mass: " + str(be.atomic_weight) + "\n" + "Atomic number: " + str(be.atomic_number))
        labelbe.after(5500, lambda: labelbe.config(text=''))
        labelbe.pack()
    
    
    class Window(Frame):
        def __init__(self, master=None):
            Frame.__init__(self, master)
            self.master = master
            self.init_window()
    
        # Creation of init_window
        def init_window(self):
            # changing the title of our master widget
            self.master.title("Interactive Periodic Table v1")
            # allowing the widget to take the full space of the root window
            self.pack(fill=BOTH, expand=1)
            # creating a button instance
            hbutton = Button(self, text="Hydrogen - H", command=callback_h)
            # placing the button on my window
            hbutton.place(x=0, y=0)
            # all other elements
            hebutton = Button(self, text="Helium - He", command=callback_he)
            hebutton.place(x=100, y=0)
    
            libutton = Button(self, text="Lithium - Li", command=callback_li)
            libutton.place(x=190, y=0)
    
            bebutton = Button(self, text="Beryllium - Be", command=callback_be)
            bebutton.place(x=275, y=0)
    
    
    # size of the window
    root.geometry("600x500")
    app = Window(root)
    root.mainloop()