항목, 목록 상자 (드롭 다운) 및 다른 목록 상자가 있습니다. 항목 내에 3 자 이상이 입력 될 때마다. 완료 목록이 조회되어 드롭 다운에 삽입되고 드롭 다운이 표시됩니다. 항목이 드롭 다운에서 선택되는 경우. 값이 항목을 채워야하고 항목이 다시 초점을 가져와 커서가 항목의 끝으로 가야합니다. 그런 다음 Enter 키를 누르면 항목의 값을 다른 목록 상자에 삽입해야합니다.python - StringVar()에서 set()을 호출하면 tkinter 위젯에 바인딩됩니다.
나는 this 유틸리티로부터 많은 도움을 받아 코드를 개발했으며 코드는 완벽하게 작동합니다. 나는 드롭 다운에서 옵션을 선택할 때마다 해당 메소드가 두 번 호출됨을 알았습니다. (같은 것을 콘솔에 두 개 찍었습니다.) 그러나 드롭 다운의 첫 번째 옵션을 선택하면 한 번 호출됩니다 (실제로 다른 경우에 발생해야하는 것입니다). 그러나 포커스가 항목 (항목)으로 이동하지 않습니다. 그래서
from tkinter import *
class Autocomplete(Frame, object):
def __init__(self, width, height, entries, *args, **kwargs):
super(Autocomplete, self).__init__(*args, **kwargs)
self._entries = entries
self.listbox_height = height
self.entry_width = width
self.text = StringVar()
self.entry = Entry(
self,
textvariable=self.text,
width=self.entry_width
)
self.frame = Frame(self)
self.listbox = Listbox(
self.frame,
height=self.listbox_height,
width=self.entry_width
)
self.dropdown = Listbox(
self.frame,
height=self.listbox_height,
width=self.entry_width,
background="#cfeff9"
)
def build(self):
self.text.trace("w", lambda name, index, mode, text=self.text: self._update_autocomplete())
self.entry.bind("<Return>", lambda event,: self._add_course())
self.entry.focus_set()
self.entry.pack()
self.frame.pack()
self.listbox.grid(column=0, row=0, sticky=N)
self.dropdown.bind("<<ListboxSelect>>", self._select_entry)
self.dropdown.grid(column=0, row=0, sticky=N)
self.dropdown.grid_forget()
return self
def _update_autocomplete(self):
self.dropdown["height"] = self.listbox_height
self.dropdown.delete(0, END)
text = self.text.get()
if len(text) < 3:
self.dropdown.grid_forget()
return
else:
for entry in self._entries:
if text.lower() in entry.strip().lower():
self.dropdown.insert(END, entry)
listbox_size = self.dropdown.size()
if not listbox_size:
self.dropdown.insert(END, "No results found for '{}'")
self.dropdown["height"] = 1
else:
if listbox_size <= self.dropdown["height"]:
self.dropdown["height"] = listbox_size
self.dropdown.grid(column=0, row=0, sticky=N)
def _select_entry(self, event):
widget = event.widget
value = widget.get(int(widget.curselection()[0]))
print(value)
self.text.set(value)
self.entry.focus_set()
self.entry.icursor(END)
def _add_course(self):
self.listbox.insert(END, self.text.get())
내가 여기서 무엇을 놓치고 : 여기
내 코드?
그런데 코드에 대한 일반적인 개선도 크게 감사 할 것입니다. 여기
그리고 내가 그것을 호출하는 방법이다 : 당신이 항목을 클릭하면 목록 상자의
from tkinter import *
from autocomplete import Autocomplete
from main import *
courses = load_courses_from_file("courses.txt")
root = Tk()
autocomplete_frame = Autocomplete(
60,
10,
list(set(course.name + ", " + course.instructor for course in courses))
).build().pack()
mainloop()
코드가 게시 된 상태로 실행되지 않습니다. –
@BryanOakley 무엇을 의미합니까? 내가 전화하지 않았다는 뜻이야? 그렇다면 나는 그 지위를 편집했다. 그렇지 않으면, 확실합니까? BC 내가 생각하기에 나는 코드를 붙여 넣었다고 생각합니다! –