Виджет Listbox

От класса Listbox создаются списки – виджеты, внутри которых в столбик перечисляются элементы. При этом можно выбирать один или множество элементов списка.

В Tkinter сначала создается экземпляр Listbox, после этого он заполняется с помощью метода insert().

Listbox

Первым аргументом в insert() передается индекс места, куда будет вставлен элемент. Если нужно вставлять в конец списка, то индекс обозначают константой END. Вторым аргументом передается вставляемый элемент.

По-умолчанию в Listbox, кликая мышкой, можно выбирать только один элемент. Если необходимо обеспечить множественный выбор, то для свойства selectmode можно установить значение EXTENDED. В этом режиме можно выбрать сколь угодно элементов, зажав Ctrl или Shift.

Если для Listbox необходим скроллер, то он настраивается также как для текстового поля. В программу добавляется виджет Scrollbar и связывается с экземпляром Listbox.

С помощью метода get() из списка можно получить один элемент по индексу, или срез, если указать два индекса. Метод delete() удаляет один элемент или срез.

Метод curselection() позволяет получить в виде кортежа индексы выбранных элементов экземпляра Listbox.

Ниже приводится пример программы, иллюстрирующей применение методов get(), insert(), delete() и curselection() класса Listbox. Первая кнопка добавляет введенную пользователем в текстовое поле строку в список, вторая кнопка удаляет выбранные элементы из списка, третья – сохраняет список в файл.

Методы Listbox

from tkinter import *
 
def addItem():
    lbox.insert(END, entry.get())
    entry.delete(0, END)
 
def delList():
    select = list(lbox.curselection())
    select.reverse()
    for i in select:
        lbox.delete(i)
 
def saveList():
    f = open('list000.txt', 'w')
    f.writelines("\n".join(lbox.get(0, END)))
    f.close()
 
root = Tk()
 
lbox = Listbox(selectmode=EXTENDED)
lbox.pack(side=LEFT)
scroll = Scrollbar(command=lbox.yview)
scroll.pack(side=LEFT, fill=Y)
lbox.config(yscrollcommand=scroll.set)
 
f = Frame()
f.pack(side=LEFT, padx=10)
entry = Entry(f)
entry.pack(anchor=N)
badd = Button(f, text="Add", command=addItem)
badd.pack(fill=X)
bdel = Button(f, text="Delete", command=delList)
bdel.pack(fill=X)
bsave = Button(f, text="Save", command=saveList)
bsave.pack(fill=X)
 
root.mainloop()

В функции delList() кортеж выбранных элементов превращается в список, после чего выполняется его реверс, т. е. переворот. Это делается для того, чтобы удаление элементов происходило с конца списка. Иначе программа бы неверно работала, так как удаление элемента приводило бы к изменению индексов всех следующих за ним. Если же удалять с конца, то индексы впереди стоящих не меняются.

В функции saveList() кортеж строк-элементов, который вернул метод get(), преобразуется в одну строку с помощью строкового метода join() через разделитель '\n'. Это делается для того, чтобы элементы списка записались в файл столбиком.

Listbox – достаточно сложный виджет. Кроме рассмотренных он обладает другими методами, а также множеством свойств.

Практическая работа

Напишите программу, состоящую из двух списков Listbox. В первом будет, например, перечень товаров, заданный программно. Второй изначально пуст, пусть это будет перечень покупок. При клике на одну кнопку товар должен переходить из одного списка в другой. При клике на вторую кнопку – возвращаться (человек передумал покупать). Предусмотрите возможность множественного выбора элементов списка и их перемещения.

Пример использования списка

Курс с примерами решений практических работ: android-приложение, pdf-версия.

Комментарии

Решение практической работы:
prod_two = Listbox(width=25,height=10, selectmode=EXTENDED)
for i in ("Молоко", "Колбоса", "Котлетки", "С пюрешкой", "Г"):
	prod_two.insert(0,i)
def vlev():
	pr1 = prod_two.curselection()
	pr2 = prod_two.get(pr1)
	prod_one.insert(END,pr2)
	prod_two.delete(pr1)
def vprav():
	pr1 = prod_one.curselection()
	pr2 = prod_one.get(pr1)
	prod_two.insert(END,pr2)
	prod_one.delete(pr1)
butt_one = Button(text="<<<", width=5,height=1, command=vlev)
butt_two = Button(text=">>>", width=5,height=1, command=vprav)
prod_one.pack(side=LEFT)
prod_two.pack(side=RIGHT)
butt_one.pack()
butt_two.pack()
root.mainloop()

Практическая работа.
from tkinter import *
root=Tk()
 
def to_box_2():
    select=list(box_1.curselection())
    select.reverse()
    for i in select:
        box_2.insert(END, box_1.get(i))
        box_1.delete(i)
 
 
def to_box_1():
    select=list(box_2.curselection())
    select.reverse()
    for i in select:
        box_1.insert(END, box_2.get(i))
        box_2.delete(i)
 
 
box_1=Listbox(selectmode=EXTENDED)
box_1.pack(side=LEFT)
products=["apple", "banana","carrot", "bread", "butter", "meat", "potato", "pineapple", "milk", "tomato"]
for p in products:
    box_1.insert(END, p)
scroll=Scrollbar(command=box_1.yview)
scroll.pack(side=LEFT, fill=Y)
box_1.config(yscrollcommand=scroll.set)
 
f=Frame()
f.pack(side=LEFT)
 
Button(f, text=">>>", command=to_box_2). pack()
Button(f, text="<<<", command=to_box_1).pack()
box_2=Listbox(selectmode=EXTENDED)
box_2.pack(side=LEFT)
scroll=Scrollbar(command=box_2.yview)
scroll.pack(side=LEFT, fill=Y)
box_2.config(yscrollcommand=scroll.set)
 
root.mainloop()

from tkinter import *
 
 
def order():
    select = list(product_list.curselection())
    select.reverse()
    for i in select:
        shopping_list.insert(0, product_list.get(i))
        product_list.delete(i)
 
#  Sorting the list of goods alphabetically.
    l = list(shopping_list.get(0, END))
    l.sort()
    shopping_list.delete(0, END)
    for product in l:
        shopping_list.insert(END, product)
 
 
def delete():
    select = list(shopping_list.curselection())
    select.reverse()
    for i in select:
        product_list.insert(0, shopping_list.get(i))
        shopping_list.delete(i)
 
#  Sorting the list of goods alphabetically.
    l = list(product_list.get(0, END))
    l.sort()
    product_list.delete(0, END)
    for product in l:
        product_list.insert(END, product)
 
 
root = Tk()
root.title("Listbox")
 
frame = Frame()
 
product_list = Listbox(font="Courier 12", bg='#ADD8E6',
                       fg='#191970', selectmode=EXTENDED)
for i in (' apple', ' butter', ' cheese', ' chicken', ' fish', ' jam', 
          ' juice', ' lemon', ' meat', ' milk', ' tea', ' tomato', ' water'):
    product_list.insert(END, i)
 
shopping_list = Listbox(font="Courier 12", bg='#ADD8E6', fg='#191970', 
                        selectmode=EXTENDED)
 
scroll_product_list = Scrollbar(command=product_list.yview)
scroll_shopping_list = Scrollbar(command=shopping_list.yview) 
 
product_list.config(yscrollcommand=scroll_product_list.set)
shopping_list.config(yscrollcommand=scroll_shopping_list.set)
 
order_button = Button(frame, width=10, text="Order >>", font=18, command=order)
delete_button = Button(frame, width=10, font=18, text="<< Return", command=delete)
 
product_list.pack(side=LEFT, expand=1, fill=BOTH)
scroll_product_list.pack(side=LEFT, fill=Y)
frame.pack(padx=1, side=LEFT, expand=1, fill=BOTH)
order_button.pack(expand=1, fill=X)
delete_button.pack(expand=1, fill=X)
scroll_shopping_list.pack(side=LEFT, fill=Y)
shopping_list.pack(side=LEFT, expand=1, fill=BOTH)
 
root.mainloop()

from tkinter import *
root = Tk()
fr1 = Frame()
fr2 = Frame()
fr3 = Frame()
 
fruits = ['apple',"bananas","carrot","bread","butter","meat","milk","potato","pineapple"]
fruits2 = []
 
def sel():
    if lBox.curselection() != '':
        a = list(lBox.curselection())
        a.reverse()
        for i in a:
            lBox2.insert(END,lBox.get(i))
            lBox.delete(i)
def sel2():
    if lBox2.curselection() != '':
        a = list(lBox2.curselection())
        a.reverse()
        for i in a:
            lBox.insert(END,lBox2.get(i))
            lBox2.delete(i)
 
lBox = Listbox(fr1, selectmode = EXTENDED)
for i in fruits:
    lBox.insert(END,i)
b1 = Button(fr2,width = 10,text= '>>>', command = sel)
b2 = Button(fr2,width = 10,text= '<<<',command = sel2)
 
for i in fruits2:
    lBox.insert(END,i)
lBox2 = Listbox(fr3,selectmode = EXTENDED)
 
lBox.pack()
b1.pack()
b2.pack()
lBox2.pack()
 
fr1.pack(side = LEFT)
fr2.pack(side = LEFT)
fr3.pack(side = LEFT)
root.mainloop()

Ответ на от Павел

from tkinter import *
 
root = Tk()
 
 
def Vpravo():
    select = list(lbox1.curselection())
    select.reverse()
    for i in select:
        lbox2.insert(END, lbox1.get(i))
        lbox1.delete(i)
 
def Vlevo():
    select = list(lbox2.curselection())
    select.reverse()
    for i in select:
        lbox1.insert(END, lbox2.get(i))
        lbox2.delete(i)
 
f1=Frame()
lbox1 = Listbox(f1, selectmode=EXTENDED, width=15, height = 8)
f1.pack(side=LEFT)
lbox1.pack(side=LEFT, anchor=W)
 
f2=Frame()
toLeft = Button(f2, text='<<<', command=Vlevo)
toRight = Button(f2, text='>>>', command=Vpravo)
f2.pack(side=LEFT)
toLeft.pack()
toRight.pack()
 
f3=Frame()
lbox2 = Listbox(selectmode=EXTENDED,width=15, height = 8)
lbox2.pack(side= LEFT, anchor=E)
 
for i in range(10):
    lbox1.insert(END,i)
 
root.mainloop()