-1

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.

2 Answers2

1

You could keep a reference of your labels in a list then during your callback just iterate through them and change their text/destroy/hide/show them as necessary.

def callback:
  for lbl in my_labels:
    # Destroy the previous labels
    lbl.destroy()
    # Or disable it using something like lbl.pack_forget()
  # Create new label or whatever
  new_label = Label(root... etc, etc.
MrGVSV
  • 127
  • 2
  • 7
  • Could you elaborate a little bit more? I'm not the greatest at coding, so formatting it exactly like my code above would be greatly appreciated. Thanks! – Alexander Dua Nov 22 '19 at 03:49
0

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()