私は、これは少なくとも一つの単語のために働くことを得るために変更しなければならなかったので、いくつかのこと。現在、連続した文字列でさらに多くの単語を入力し続ける場合は機能しません。
私は最終的にはうまくいくと確信していますが、リストボックスから単語を更新してエントリフィールドに戻ってくるという問題に答えようとしています。
私はいくつかの変更が必要でした。
index = int(self.dropdown.curselection()[0])
へ:
index = self.dropdown.curselection()[0]
self.dropdown.curselection()[0]
の戻り値は、すでにintですよう
は、最初に私が変更しなければなりませんでした。整数を再び整数にする必要はありません。
第二に、私は変更しなければならなかった:
def _add_course(self, value):
self.listbox.insert(END, value)
self.my_list.append(value)
へ:
def _add_course(self, value):
self.entry.delete(0,END)
self.entry.insert(END, value)
self.my_list.append(value)
あなたがリストボックスにvalue
ない入力フィールドを挿入しようとしていたとして。また、self.list
をself.my_list`に変更しました。組み込み関数を上書きするような名前は付けないでください。
最後に私が変更する必要があったのは、フォーカスを入力欄に戻す方法でした。フォーカスの問題は、マウスクリックに焦点を当てているにもかかわらず、まだリストボックスをクリックしていて、それがフォーカスしているということです。フォーカスが入力フィールドに設定される前に、マウスクリックを終了する時間があるように、フォーカスセットに遅延を追加する必要があります。
変更:
self.entry.focus_set()
へ:
self.master.after(200, lambda: self.entry.focus())
バック入力フィールドにフォーカスを設定する代わりに、代わりにbind()
にフォーカスコマンドにボタンのリリースイベントになります。
あなたにも、このようにフォーカスを強制することができます。
self.dropdown.bind("<ButtonRelease-1>", lambda x: self.entry.focus())
次のコードは、あなたの主な問題のために働く必要があります。
from tkinter import *
class Autocomplete(Frame, object):
def __init__(self, width, height, entries, *args, **kwargs):
super(Autocomplete, self).__init__(*args, **kwargs)
self.my_list = []
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: self._update_dropdown())
self.entry.focus_set()
self.entry.pack()
self.frame.pack()
self.listbox.grid(column=0, row=0, sticky=N)
self.dropdown.bind("<<ListboxSelect>>", lambda event: self._select_entry())
self.dropdown.grid(column=0, row=0, sticky=N)
self.dropdown.grid_forget()
return self
def _update_dropdown(self):
self.dropdown["height"] = self.listbox_height
self.dropdown.delete(0, END)
text = self.text.get()
print("update: " + text)
if len(text) < 3:
self.dropdown.grid_forget()
return
else:
for entry in self._entries:
if entry not in self.my_list and text.lower() in entry.lower():
self.dropdown.insert(END, entry)
listbox_size = self.dropdown.size()
if not listbox_size:
self.dropdown.insert(END, "No results found for '{}'".format(text))
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 _shorten_dropdown(self, index):
print("shorten: {}".format(str(index)))
self.dropdown.grid_forget()
self.dropdown.delete(index)
if self.dropdown["height"] == 1:
self.dropdown.insert(END, "No more results found for '{}'".format(self.text.get()))
else:
self.dropdown["height"] -= 1
self.dropdown.selection_clear(0, END)
self.dropdown.grid(column=0, row=0, sticky=N)
def _select_entry(self):
index = self.dropdown.curselection()[0]
value = self.dropdown.get(index)
print(value)
if "results found for" in value:
print("return")
return
print("select: {}".format(value))
self._shorten_dropdown(index)
self._add_course(value)
self.master.after(200, lambda: self.entry.focus())
def _add_course(self, value):
self.entry.delete(0,END)
self.entry.insert(END, value)
self.my_list.append(value)
listt = ["a","aa","aaa","ab","bba","aba","abbnb","cd","c","abc","abcd"]
root = Tk()
autocomplete_frame = Autocomplete(60, 10, listt).build()
autocomplete_frame.pack()
mainloop()
あなたのコードがテスト可能ではありません。コードをコピーしてコピーして、問題が何であるかを確認する必要があります。あなたのコードをテストできるように、[最小、完全、および検証可能な例](https://stackoverflow.com/help/mcve)を提供してください。 –
@ Mike-SMT完全なコードへのリンクを追加しました。 –
あなたの「テスト可能バージョン」へのリンクはまだテスト可能ではありません。どのように 'Autocomplete()'のオブジェクトインスタンスを作成していますか?そのクラスを呼び出すコードはありません。すべてのコードを提供する必要はありません。ちょうどMCVE。これは問題のメソッドと、tkinterインスタンスの作成方法を含めるだけです。あなたのコードには 'Tk()'や 'mainloop()'はなく、tkinterを実行するために必要です。クラスの実装方法を推測することなく、サンプルをコピーしてコピーできるようにする必要があります。 –