Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » Tkinter, Listbox поверх основного окна. [RSS Feed]

#1 Апрель 11, 2017 14:27:45

Kemok
Зарегистрирован: 2017-04-11
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, Listbox поверх основного окна.

Приветствую!
Ввиду своей неопытности столкнулся с проблемой которую уже целый день не могу решить.
В окне есть виджет Entry, при печатании символов в нем появляется Listbox со списком вариантов дальнейшего написания, если есть совпадения. Когда строка в Entey перестает соответствовать неким определенным значениям, Listbox убирается.

Вот пример кода:

 import tkinter as tk
#Некий список имен
name_list = ['ahri', 'akali', 'amumu', 'annie', 'azir', 'bard', 'brand', 'caitlyn', 'camille', 'corki', 'darius', 'diana',
	'draven', 'ekko', 'elise', 'evelynn', 'ezreal', 'fiora', 'fizz', 'galio', 'gnar', 'gragas', 'graves', 'hecarim',
	'illaoi', 'irelia', 'ivern', 'janna', 'jax', 'jayce', 'jinx', 'karma', 'kayle', 'kennen', 'kindred', 'kled',
	'leona', 'lissandra', 'lucian', 'lux', 'malzahar', 'maokai', 'morgana', 'nami', 'nautilus', 'nidalee', 'nocturne',
	'olaf', 'orianna', 'pantheon', 'poppy', 'quinn', 'rammus', 'riven', 'rumble', 'ryze', 'sejuani', 'singed',	'skarner',
	'syndra', 'talon', 'teemo', 'tristana', 'trundle', 'twitch', 'udyr', 'urgot', 'varus', 'veigar', 'viktor', 'volibear',
	'warwick', 'xerath', 'yasuo', 'yorick', 'zac', 'ziggs', 'zyra']
#Создание словаря где ключами являются предполагаемые символы ввода,
#а значениями, списки имен где начальные символы совпадают с ключами.
lit = set()
for n in name_list:
	for i in range(1, 5):
		lt = n[:i]
		if [name[:i] for name in name_list].count(lt) > 1:
			lit.add(lt)
		else:
			lit.add(lt)
			break
lit_dict = {lt: [name for name in name_list if name.startswith(lt)] for lt in lit}
#Обработка события нажатия клавишь,
#сопоставление поля ввода с ключами lit_dict,
#наполнение Listbox'а значениями по этому ключу.
def sch(event):
	lis.delete(0, tk.END)
	st = ent.get()
	ch = lit_dict.get(st)
	if ch:
		for n in ch:
			lis.insert(tk.END, n)
		lis.pack()
	else:
		lis.pack_forget()
root = tk.Tk()
ent = tk.Entry(root)
lis = tk.Listbox(root)
ent.bind('<KeyRelease>', sch)
ent.pack()
root.mainloop()

Все работает, но мне нужно чтобы Listbox появлялся поверх основного окна, а не встраивался в него.
Предполагаю что решение простое, но я его не вижу. Пробовал делать класс на основе Frame'а и Toplevel'а, не вышло.

Офлайн

#2 Апрель 12, 2017 07:36:00

Kemok
Зарегистрирован: 2017-04-11
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter, Listbox поверх основного окна.

Сделал через Toplevel следующим образом:

 import tkinter as tk
class Listch(tk.Toplevel):
	def __init__(self):
		tk.Toplevel.__init__(self, root)
		self.overrideredirect(True)
		self.withdraw()
		self.lis = tk.Listbox(self, selectmode=tk.SINGLE, width=15)
		self.lis.pack(fill=tk.BOTH, expand=1)
		ent.bind('<KeyRelease>', self.sch)
	def sch(self, event):
		self.lis.delete(0, tk.END)
		st = ent.get()
		ch = lit_dict.get(st)
		if ch:
			self.geometry('+{}+{}'.format(root.winfo_x()+5, root.winfo_y()+40))
			self.lis.config(height=len(ch))
			self.deiconify()
			for n in ch:
				self.lis.insert(tk.END, n)
		else: self.withdraw()
#Некий список имен
name_list = ['ahri', 'akali', 'amumu', 'annie', 'azir', 'bard', 'brand', 'caitlyn', 'camille', 'corki', 'darius', 'diana',
	'draven', 'ekko', 'elise', 'evelynn', 'ezreal', 'fiora', 'fizz', 'galio', 'gnar', 'gragas', 'graves', 'hecarim',
	'illaoi', 'irelia', 'ivern', 'janna', 'jax', 'jayce', 'jinx', 'karma', 'kayle', 'kennen', 'kindred', 'kled',
	'leona', 'lissandra', 'lucian', 'lux', 'malzahar', 'maokai', 'morgana', 'nami', 'nautilus', 'nidalee', 'nocturne',
	'olaf', 'orianna', 'pantheon', 'poppy', 'quinn', 'rammus', 'riven', 'rumble', 'ryze', 'sejuani', 'singed',	'skarner',
	'syndra', 'talon', 'teemo', 'tristana', 'trundle', 'twitch', 'udyr', 'urgot', 'varus', 'veigar', 'viktor', 'volibear',
	'warwick', 'xerath', 'yasuo', 'yorick', 'zac', 'ziggs', 'zyra']
#Создание словаря где ключами являются предполагаемые символы ввода,
#а значениями, списки имен где начальные символы совпадают с ключами.
lit = set()
for n in name_list:
	for i in range(1, 5):
		lt = n[:i]
		if [name[:i] for name in name_list].count(lt) > 1:
			lit.add(lt)
		else:
			lit.add(lt)
			break
lit_dict = {lt: [name for name in name_list if name.startswith(lt)] for lt in lit}
root = tk.Tk()
ent = tk.Entry(root)
ent.pack()
Listch()
root.mainloop()

Теперь, нужно чтобы это окно было всегда поверх основного и самое главное перемещалось вместе с ним. Видимо нужно это делать через обработку события перемещения главного окна. Или есть способ проще?

Офлайн

  • Начало
  • » GUI
  • » Tkinter, Listbox поверх основного окна.[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version