1

I have a code where I am trying to print list of lists in tkinter label but it doesn't work the way I want. When I run the script below it will search the entered text in list.txt and print it in tkinter label. As more text is entered, the previous searched text should clear and new text should appear based on search results in list.txt file. But the previous text doesn't get cleared.Here's a partial code:

    import tkinter as tk
import re
from tkinter import Label

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.var = tk.StringVar()
        self.var.trace("w", self.show_message)
        self.entry = tk.Entry(self, textvariable=self.var)
        self.label = tk.Label(self)
        self.entry.pack()
        self.label.pack()
    def show_message(self, *args):
        value = self.var.get()
        scen = []
        text = "{}".format(value) if value else scen.clear()
        if text:
            words = re.split('[ ]', text.lower())
            with open('list.txt','r') as mfl:
                scen.clear()
                for line in mfl:
                    if all(word in line.lower() for word in words):
                        txt = re.split("[._ -]",line)
                        scen.append(txt[:-1])
        for i in range(len(scen)):
            exec('Label%d=Label(app,text="%s")\nLabel%d.pack()'%(i,scen[i],i))


if __name__ == "__main__":
    app = App()
    app.mainloop()
Tila Tripy
  • 45
  • 9
  • Try this approach: [Print tabular formated text into a tk.Text widget](https://stackoverflow.com/a/59346200/7414759) – stovfl Mar 04 '20 at 17:01
  • Scen is an empty list. When one enters text in the widget, the searched text from list.txt is appended to this scen list which is printed in the label. As you enter more text the widget, the previous text in scen is cleared(scen.clear()) and new searched text is appended which is again printed in the label – Tila Tripy Mar 04 '20 at 17:17
  • 1
    You should use a `Frame` to hold the result labels. When showing new search result, delete all labels in the frame before adding new labels. Also using `exec(...)` is not necessary, use `Label(self, text=scen[i]).pack()` instead. – acw1668 Mar 04 '20 at 18:58
  • standard rule: `"if you have many elements then keep them on list"`. So keep labels on list and you will no need to use `exec()` and later you can use `for`-loop to `destroy()` all labels from list to remove them from window. – furas Mar 04 '20 at 21:36

1 Answers1

1

Standard rule:

"if you have many elements then keep them on list"    

You should keep labels on list and then you don't have to use exec() to create variables Label%d and later you can use for-loop to destroy() all labels before you add new labels.

import tkinter as tk
import re
from tkinter import Label

class App(tk.Tk):

    def __init__(self):
        super().__init__()
        self.var = tk.StringVar()
        self.var.trace("w", self.show_message)
        self.entry = tk.Entry(self, textvariable=self.var)
        self.label = tk.Label(self)
        self.entry.pack()
        self.label.pack()

        # list for all labels
        self.all_labels = []


    def show_message(self, *args):
        text = self.var.get()
        scen = []
        if text:
            words = text.lower().split(' ')
            with open('list.txt') as mfl:
                scen.clear()
                for line in mfl:
                    if all(word in line.lower() for word in words):
                        txt = re.split("[._ -]", line)
                        scen.append(txt[:-1])

        # remove all labels
        for item in self.all_labels:
            item.destroy()
        self.all_labels.clear()   # remove references to old labels (as @acw1668  noticed in comment)

        # add new labels
        for item in scen:
            l = tk.Label(self, text=item)
            l.pack()
            self.all_labels.append(l)

if __name__ == "__main__":
    app = App()
    app.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148
  • Better to call `self.all_labels.clear()` before inserting new labels inside `show_message()`, otherwise it will be kept expanding with references to already destroyed labels. – acw1668 Mar 05 '20 at 00:54