Once again I need your knowledge. I have written a small script to display a listbox and I would like to do two things.
I) : print in a label on the right side of the window the item selected and delete the label if user is deselecting the item
II) : Add a line between each label if some items are selected
I can display items but in a single line and by deselecting items in the listbox, label is not removed
Thanks in advance for your help
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()
CodePudding user response:
Here is an update on your code. I've simplified printSelection
by creating all Labels
with blank text. This means every item in self.list
has a unique Label
.
I also changed pack managed objects to place managed.
Not sure if this is exactly what you are looking for but now it works and should give you an idea on how to proceed.
Also I have inserted remarks into code that describe changes.
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()
To use your original selectmode settings printSelection
needs to change.
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"] = ""