Listbox

عنصر Listbox برای نمایش لیستی از آیتم‌ها استفاده می‌شود که کاربر می‌تواند یک یا چند آیتم را از میان آنها انتخاب کند. نحوه ایجاد این عنصر به شکل ساده به صورت زیر است:

Listbox (master, option, ...)

master، بیانگر پنجره والدی است که Listbox به آن تعلق خواهد داشت و Options، تنظیمات پرکاربرد برای Listbox می‌باشند که می‌توانند به صورت زوج‌های کلید/مقدار که با ویرگول از هم جدا می‌شوند، مورد استفاده قرار گیرند. در جدول زیر لیست این تنظیمات آمده است:

تنظیمات شرح
bg رنگ پس زمینه در حالت عادی
bd اندازه خط اطراف عنصر است (پیش فرض 2 پیکسل).
cursor نشانگر ماوس، زمانی که ماوس بر روی این عنصر قرار می‌گیرد را تعیین می‌کند.
font فونتی که برای متن درون listbox استفاده می‌شود.
fg رنگ متن را مشخص می‌کند.
height ارتفاع ListBox بر اساس تعداد خطوط، (نه بر اساس پیکسل) که در listbox نمایش داده می‌شود (پیش فرض 10 است).
highlightcolor رنگ فوکوس نمایش داده شده، زمانی که عنصر دارای فوکوس است.
highlightthickness ضخامت فوکوس نمایش داده شده، را تعیین می‌کند.
relief افکت خط حاشیه listbox را مشخص می‌کند. مقدار پیش فرض SUNKEN است.
selectbackground رنگ پس زمینه آیتم انتخاب شده را تعیین می‌کند.
selectmode مشخص می‌کند چه تعداد آیتم می‌تواند انتخاب شود.

  • BROWSE: به طور معمول تنها یک خط از listbox را می‌توانید با کلیک ماوس انتخاب کنید. اگر بر روی یک آیتم کلیک کنید و در همان حالتی که ماوس را گرفته‌اید بر روی آیتم‌ها جا به جاو شوید، آیتم انتخاب شده همراه با ماوس تغییر می‌کند. این حالت پیش فرض است.
  • SINGLE: تنها می‌توان یک خط را انتخاب کرد. اما ماوس را نمی‌توان همزمان بر روی آیتم‌ها جا به جا کرد.
  • MULTIPLE: می‌توانید چندین خط را انتخاب کنید. همچنین با کلیک بر روی هر خط، وضعیت انتخاب آن تغییر می‌کند.
  • EXTENDED: می‌توانید گروهی از آیتم‌ها را با کلیک بر روی یک آیتم و کشیدن ماوس بر روی بقیه، انتخاب کنید.
width پهنای عنصر Listbox بر اساس حرف (پیش فرض 20 است).
xscrollcommand اگر می‌خواهید کاربر بتواند به صورت افقی listbox را اسکرول کند، با این گزینه می‌توانید listbox را به اسکرول بار متصل کنید.
yscrollcommand همانند xscrollcommand، اما برای اسکرول عمودی.

توابع listbox شامل موارد زیر است:

تابع شرح
activate(index) خط مشخص شده با index را فعال می‌کند.
()curselection یک Tuple، شامل شماره خطوط آیتم‌های انتخاب شده را، بر می‌گرداند. (شروع از صفر) در صورتی که آیتمی انتخاب نشده باشد، Tuple خالی خواهد بود.
delete(first, last=None) خطوط در بازه [first,last] را حذف می‌کند. اگر آرگومان دوم ارسال نشود، تنها خط first حذف می‌شود.
get(first, last=None) یک Tuple، شامل متن خطوط از first تا last را بر می‌گرداند.
index(i) در صورت امکان، قسمت قابل مشاهده لیست باکس را به گونه‌ای تنظیم می‌کند، تا آیتم در موقعیت i، در بالای لیست باکس قرار گیرد.
insert(index, *elements) یک یا چند خط را قبل از خط مشخص شده با index، اضافه می‌کند. از END برای اضافه کردن آیتم در انتهای لیست استفاده کنید.
nearest(y) اندیس نزدیک‌ترین خط قابل مشاهده با فاصله عمودی y نسبت به عنصر لیست باکس را بر می‌گرداند.
see(index) وضعیت لیست باکس را به گونه‌ای تنظیم می‌کند تا خط index قابل مشاهده باشد.
()size تعداد خطوط لیست باکس را بر می‌گرداند.
()xview برای اینکه لیست باکس به صورت افقی قابل اسکرول باشد، گزینه command اسکرول بار را با این تابع مقداردهی کنید.
xview_moveto(fraction) fraction عددی در بازه [0,1] است و مشخص کننده نسبت فاصله افقی تا سمت چپ لیست باکس است. این تابع لیست را به گونه‌ای به صورت افقی اسکرول می‌کند تا سمت چپ لیست باکس تا fraction بیرون از سمت چپ قرار بگیرد. (از fraction به بعد قابل مشاهده باشد)
xview_scroll(number, what) لیست باکس را به صورت افقی اسکرول می‌کند. آرگومان what باید یا مقدار UNITS (اسکرول به اندازه پهنای حرف) یا PAGES (اسکرول به اندازه پهنای لیست باکس) داشته باشد. آرگومان number بیانگر این است که چه تعدادی از این واحدها اسکرول انجام شود.
()yview برای اینکه لیست باکس به صورت عمودی قابل اسکرول باشد، گزینه command اسکرول بار عمودی را با این تابع مقداردهی کنید.
yview_moveto(fraction) fraction عددی در بازه [0,1] است و مشخص کننده نسبت فاصله عمودی تا بالای لیست باکس است. این تابع لیست را به گونه‌ای به صورت عمودی اسکرول می‌کند تا بالای لیست باکس تا fraction بیرون قرار بگیرد.
yview_scroll(number, what) لیست باکس را به صورت عمودی اسکرول می‌کند. آرگومان what باید یا مقدار UNITS (اسکرول به اندازه خطوط) یا PAGES (اسکرول به اندازه ارتفاع لیست باکس) داشته باشد. آرگومان number بیانگر تعداد این واحدها برای اسکرول است.

حال درباره برخی از خواص و متدهای عنصر ListBox توضیح دهیم. کد زیر را نوشته :

 1: import tkinter
 2: from tkinter import *
 3: 
 4: window = tkinter.Tk()
 5: window.geometry('300x200')
 6: 
 7: listbox1 = Listbox(window)
 8: 
 9: dictionary = {
10:                 "Shampoo"    : "Makes your hair beautiful and shiny.",
11:                 "Soap"       : "Removes the dirt and germs on your body.",
12:                 "Deodorant"  : "Prevents body odor.",
13:                 "Toothpaste" : "Used to clean your teeth.",
14:                 "Mouthwash"  : "Fights bad breath."
15:              }
16: 
17: listbox1.pack()
18: 
19: for key in dictionary:
20:     listbox1.insert(END, key)
21: 
22: window.mainloop()

و سپس برنامه را اجرا کنید:
listbox-in-tkinter-01
ممکن است برخی از خطوط کد بالا برایتان نا مفهوم باشد. اما مهم نیست در ادامه آنها را توضیح می‌دهیم. همانطور که گفتیم از خاصیت selectmode برای نحوه انتخاب آیتم‌های ListBox استفاده می‌شود. حال خط 7 کد بالا را به صورت زیر تغییر دهید:

listbox1 = Listbox(window, selectmode=MULTIPLE)

برنامه را اجرا و بر روی تک تک آیتمها کلیک و نتیجه را مشاهده کنید:
listbox-in-tkinter-02
حال همین خط را به صورت زیر ویرایش نمایید:

listbox1 = Listbox(window, selectmode=MULTIPLE, selectbackground="red")

با اجرای برنامه مشاهده می‌کنید که رنگ پس زمینه آیتم انتخاب شده به صورت قرمز در می‌آید:
listbox-in-tkinter-03
برای تغییر رنگ ListBox وقتی که به حالت فوکوس در می‌آید، خط 7 را به صورت زیر تغییر دهید:

listbox1 = Listbox(window, selectmode=MULTIPLE, selectbackground="red", highlightcolor="yellow")

با اجرای برنامه و کلیک بر روی ListBox رنگ خط کناری آن به صورت زرد در می‌آید:
listbox-in-tkinter-04
حال نوبت به عرض و ارتفاع ListBox می‌رسد. خط 7 را به صورت زیر تغییر دهید:

listbox1 = Listbox(window, width=5, height=3)

با اجرای برنامه، ارتفاع ListBox به اندازه 3 خط و عرض آن به اندازه 5 کاراکتر کوچک در می‌آید:
listbox-in-tkinter-05

حال نوبت متدهای ListBox می‌رسد. در خط 21 کد بالا، خط زیر را اضافه کنید:

listbox1.delete(2)

با اجرای برنامه مشاهده می‌کنید که خطی که دارای اندیس 2 است یعنی خط سوم حذف می‌شود:
listbox-in-tkinter-06

حال آرگومانی دیگر به متد بالا اضافه کنید:

listbox1.delete(2, 4)

با اجرای برنامه، مشاهده می‌کنید که خطوط 3، 4 و 5 از ListBox حذف می‌شوند. کد بالا به این معناست که خطوط که دارای اندیس‌های 2، 3 و 4 را حذف کن:
listbox-in-tkinter-07
برای اضافه کردن یک یا چند آیتم به ListBox از تابع ()insert استفاده می‌کنیم. خط 21 را پاک کرده و خط زیر را جایگزین آن کنید:

listbox1.insert(2, "Oil")

با اجرای کد، بعد از خطی که دارای اندیس 2 است کلمه Oil اضافه می‌شود:
listbox-in-tkinter-08
به جای عدد 2 کلمه END را نوشته و برنامه را اجرا و نتیجه را مشاهده کنید. برای به دست آوردن تمامی یا تعدادی از آیتم‌های ListBox از متد ()get استفاده می‌شود. این متد آیتم یا آیتم‌های انتخاب شده را در داخل یک Tuple قرار می‌دهد. به کد زیر توجه کنید:

listbox1.get(2, 4)

کد بالا، خطوطی 3، 4 و 5 را در داخل یک Tuple به صورت زیر می‌ریزد:

('Deodorant', 'Toothpaste', 'Mouthwash')

به یک مثال کلی‌تر در مورد نحوه استفاده از ListBox توجه کنید:

 1: import tkinter
 2: from tkinter import *
 3: 
 4: window = tkinter.Tk()
 5: window.geometry('300x200')
 6: 
 7: listbox1 = Listbox(window)
 8: listbox2 = Listbox(window)
 9: 
10: listbox1.pack(side=LEFT)
11: listbox2.pack(side=RIGHT)
12: 
13: dictionary = {
14:                 "Shampoo"    : "Makes your hair beautiful and shiny.",
15:                 "Soap"       : "Removes the dirt and germs on your body.",
16:                 "Deodorant"  : "Prevents body odor.",
17:                 "Toothpaste" : "Used to clean your teeth.",
18:                 "Mouthwash"  : "Fights bad breath."
19:              }
20: 
21: for key in dictionary:
22:     listbox1.insert(END, key)
23: 
24: def selectedindexchange(event):
25:     x = listbox1.get(listbox1.curselection())
26:     listValue = listbox2.get(0, END)
27:     if dictionary[x] not in listValue:
28:         listbox2.insert(END, dictionary[x])
29: 
30: listbox1.bind('<Double-Button-1>', selectedindexchange)
31: 
32: window.mainloop()

هدف از کد بالا این است که با کلیک بر روی آیتم‌های موجود در یک ListBox، آن‌ها را به ListBox دیگر منتقل کنیم. ابتدا دو لیست باکس در خطوط 7 و 8 ایجاد کرده و آنها را به سمت چپ و راست فرم می‌چسبانیم. در خطوط 19-13 یک دیکشنری ایجاد کرده و سپس با استفاده از یک حلقه for کلیدهای این دیکشنری را در داخل ListBox سمت چپ می‌ریزیم (خط 21 و 22). ما قرار است با دوبار کلیک بر روی هر کدام از این کلیدها، مقدار متناظر با آنها را در LisBox2 بریزیم. برای این کار یک کنترل کننده رویداد در خطوط 29-24 نوشته‌ایم. در خط 25 با استفاده از تابع ()get مقداری که با ماوس بر روی آن کلیک شده است را گرفته و در داخل یک متغیر با نام x می‌ریزیم. اما از کجا بفهمیم که بر روی کدام آیتم کلیک شده است. جواب در همین خط 25 و تابع ()curselection می‌باشد. این تابع آیتمی که بر روی آن کلیک شده یا آیتم جاری را بر می‌گرداند. در خط 26 تمام آیتم‌هایی که در داخل ListBox2 هستند را گرفته و در داخل یک متغیر به نام listValue می‌ریزیم. این کار برای برای جلوگیری از ورود اطلاعات تکراری به ListBox2 است. اما چگونه؟ dictionary[x] به معنای مقدار، مربوط به کلیدی است که بر روی آن دوبار کلیک شده. در خط 26 گفته‌ایم که اگر مقدار مربوط به کلیدی، که بر روی آن دوبار کلیک شده در ListBox2 وجود نداشت، آن را در ListBox2 بریز در غیر اینصورت خیر. در خط 28 هم این کنترل کننده رویداد را به رویداد دوبار کلیک وصل کرده‌ایم. برنامه را اجرا کرده و با دوبار کلیک بر روی آیتم‌ها، نتیجه را مشاهده کنید:
listbox-in-tkinter-09