| #!/usr/bin/env python3 | |
| # | |
| # Simple listbox with scrollbar and select button | |
| import re | |
| import tkinter | |
| from tkinter import ttk | |
| class ListBoxChoice(ttk.Frame): | |
| def __init__(self, parent, fontsize=11, *args, **kwargs): | |
| ttk.Frame.__init__(self, parent, *args, **kwargs) | |
| s = ttk.Style() | |
| s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised') | |
| def populate(self, title, list=[]): | |
| self.value = None | |
| self.list = list[:] | |
| ttk.Label(self, text=title).pack(padx=5, pady=5) | |
| listFrame = ttk.Frame(self) | |
| listFrame.pack(side='top', padx=5, pady=5, fill='both', expand='true') | |
| scrollBar = ttk.Scrollbar(listFrame) | |
| scrollBar.pack(side='right', fill='y') | |
| self.listBox = tkinter.Listbox(listFrame, selectmode='single') | |
| self.listBox.pack(side='left', fill='x', expand='true') | |
| scrollBar.config(command=self.listBox.yview) | |
| self.listBox.config(yscrollcommand=scrollBar.set) | |
| self.list.sort(key=natsort_key) | |
| for item in self.list: | |
| self.listBox.insert('end', item) | |
| if len(self.list) == 0: | |
| self.listBox.insert('end', '(no items)') | |
| else: | |
| buttonFrame = ttk.Frame(self) | |
| buttonFrame.pack(side='bottom') | |
| selectButton = ttk.Button(buttonFrame, text="Select", command=self._select, | |
| style='normal.TButton') | |
| selectButton.pack(side='left', padx = 5) | |
| listFrame.bind("<Return>", self._select) | |
| def natsort_key(s, _nsre=re.compile('([0-9]+)')): | |
| # 'natural' sort function. To make this alphabetical independently of | |
| # capitalization, use "else text.lower()" instead of "else text" below. | |
| return [int(text) if text.isdigit() else text for text in _nsre.split(s)] | |
| def _select(self, event=None): | |
| try: | |
| firstIndex = self.listBox.curselection()[0] | |
| self.value = self.list[int(firstIndex)] | |
| except IndexError: | |
| self.value = None | |
| def value(self): | |
| return self.value |