从列表框 tkinter 中取消选择项目时删除标签

delete label when deselecting item from a listbox tkinter

我再一次需要你的知识。我写了一个小脚本来显示一个列表框,我想做两件事。

I) :在 window 所选项目右侧的标签中打印,如果用户取消选择该项目,则删除标签
II) : 如果选择了某些项目,则在每个标签之间添加一条线
我可以显示项目,但在一行中并通过取消选择列表框中的项目,标签不会被删除
在此先感谢您的帮助

from tkinter import *
import tkinter as tk


class Application(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.previous_selected = None
        self.listNumber = ['One', 'Two', 'Three', 'Four', 'Five', 'Six']

        self.labellist = tk.Label(self, text=' Select a number : ')
        self.labellist.place(x=40, y=30)

        self.frame = Frame(self)
        self.frame.place(x=200, y=30)
        self.list = Listbox(self.frame, exportselection=False, height=5, selectmode="multiple")
        self.list.pack(side='left', fill='y')

        for each_item in range(len(self.listNumber)):
            self.list.insert(END, self.listNumber[each_item])
        self.scrollbar = Scrollbar(self.frame, orient="vertical", command=self.list.yview)
        self.scrollbar.pack(side='right', fill='y')
        self.list.config(yscrollcommand=self.scrollbar.set)

        self.list.bind('<<ListboxSelect>>',self.printSelection)

        self.buttonExecute = tk.Button(self, text='Execute', fg='White', bg='dark green', height=1, width=10, command=self.destroy)
        self.buttonExecute.place(x=225, y=150)

    def printSelection(self, evt):
        values = [self.list.get(idx) for idx in self.list.curselection()]
        self._label = tk.Label(self, text=' Number selected  '+', '.join(values)+'\n')
        self._label.place(x=350, y=30)
    
        if self.list.curselection() == self.previous_selected:
            self._label.place_forget()


if __name__ == "__main__":
    app = Application()
    app.geometry("600x250")
    app.mainloop()

这是您的代码更新。我通过用空白文本创建所有 Labels 来简化 printSelection。这意味着 self.list 中的每个项目都有唯一的 Label.

我也将包管理对象更改为放置管理。

不确定这是否正是您要找的东西,但现在它可以工作了,应该会让您知道如何继续。

我还在代码中插入了描述更改的注释。

import tkinter as tk

class Application(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.previous_selected = None
        self.listNumber = ["One", "Two", "Three", "Four", "Five",
                           "Six", "Seven", "Eight", "Nine"]
        self._label = dict() # label store
        # Using place with x, y
        self.labellist = tk.Label(self, anchor = tk.NW, text = " Select a number : ")
        self.labellist.place(x = 100, y = 10)
        # Using place with x, y, width, height
        self.frame = tk.Frame(self)
        self.frame.place(x = 100, y = 30, width = 300, height = 100)
        # Using place with x, y, width, height
        self.list = tk.Listbox(
            self.frame, exportselection = False, activestyle = tk.NONE,
            height = 5, selectmode = "extended")
        self.list.place(x = 2, y = 2, width = 200, height = 100)
        # Simplified populating list
        for each_item in self.listNumber:
            self.list.insert(tk.END, each_item)
        # Using place with x, y, width, height
        self.scrollbar = tk.Scrollbar(
            self.frame, orient = "vertical", command = self.list.yview)
        self.scrollbar.place(x = 210, y = 2, width = 12, height = 100)
        self.list.config(yscrollcommand = self.scrollbar.set)
        # Pre create all labels so that each label has a unique position
        for i, a in enumerate(self.listNumber):
            L = tk.Label(self, text = "")
            # Using place with x, y
            L.place(x = 350, y = i * 20)
            self._label[a] = L

        self.list.bind("<<ListboxSelect>>",self.printSelection)

        self.buttonExecute = tk.Button(
            self, text = "Execute", fg = "White",
            bg = "dark green", height = 1, width = 10, command = self.destroy)
        # Using place with x, y
        self.buttonExecute.place(x = 230, y = 140)

    def printSelection(self, evt):
        index = self.list.curselection()[ 0 ] # grab the index
        item = self.list.get(index)
        if self._label[item]["text"] == "":
            self._label[item]["text"] = f"Number selected {item}    "
        else:
            self._label[item]["text"] = ""

if __name__ == "__main__":
    app = Application()
    app.geometry("515x250")
    app.mainloop()

要使用您原来的选择模式设置,printSelection 需要更改。

    def printSelection(self, evt):
        for i,item in enumerate(self.listNumber):
            if self.list.select_includes(i):
                self._label[item]["text"] = f"Number selected {item}    "
            else:
                self._label[item]["text"] = ""