首页 > 解决方案 > 从列表框tkinter中取消选择项目时删除标签

问题描述

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

I):在窗口右侧的标签中打印所选项目,如果用户取消选择项目,则删除标签
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()

标签: tkinterlistboxlabel

解决方案


这是您的代码的更新。我通过使用空白文本printSelection创建所有内容进行了简化。Labels这意味着其中的每个项目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"] = ""

推荐阅读