具有自动完成功能的tkinter只读组合框

时间:2015-08-04 23:27:51

标签: python combobox autocomplete tkinter

我正在尝试使用python 3在tkinter中创建一个组合框,当按下第一个字母时,该组合框具有自动完成功能,但也是只读的,因此只能选择列表中的名称。

有一些旧代码适用于自动完成:

class AutocompleteCombobox(ttk.Combobox):  #https://mail.python.org/pipermail/tkinter-discuss/2012-January/003041.html

        def set_completion_list(self, completion_list):
                """Use our completion list as our drop down selection menu, arrows move through menu."""
                self._completion_list = completion_list  #sorted(completion_list, key=str.lower) # Work with a sorted list
                self._hits = []
                self._hit_index = 0
                self.position = 0
                self.bind('<KeyRelease>', self.handle_keyrelease)
                self['values'] = self._completion_list  # Setup our popup menu

        def autocomplete(self, delta=0):
                """autocomplete the Combobox, delta may be 0/1/-1 to cycle through possible hits"""
                if delta: # need to delete selection otherwise we would fix the current position
                        self.delete(self.position, END)
                else: # set position to end so selection starts where textentry ended
                        self.position = len(self.get())
                # collect hits
                _hits = []
                for element in self._completion_list:
                        if element.lower().startswith(self.get().lower()): # Match case insensitively
                                _hits.append(element)
                # if we have a new hit list, keep this in mind
                if _hits != self._hits:
                        self._hit_index = 0
                        self._hits=_hits
                # only allow cycling if we are in a known hit list
                if _hits == self._hits and self._hits:
                        self._hit_index = (self._hit_index + delta) % len(self._hits)
                # now finally perform the auto completion
                if self._hits:
                        self.delete(0,END)
                        self.insert(0,self._hits[self._hit_index])
                        self.select_range(self.position,END)

        def handle_keyrelease(self, event):
                """event handler for the keyrelease event on this widget"""
                if event.keysym == "BackSpace":
                        self.delete(self.index(INSERT), END)
                        self.position = self.index(END)
                if event.keysym == "Left":
                        if self.position < self.index(END): # delete the selection
                                self.delete(self.position, END)
                        else:
                                self.position = self.position-1 # delete one character
                                self.delete(self.position, END)
                if event.keysym == "Right":
                        self.position = self.index(END) # go to end (no selection)
                if len(event.keysym) == 1:
                        self.autocomplete()
                # No need for up/down, we'll jump to the popup
                # list at the position of the autocompletion

但挑战在于,如果将状态设置为“只读”,则不起作用:

self.combo1 = AutocompleteCombobox(mainframe, width=12, state="readonly")

我想要的是组合框跳转到列表中的第一个名字,如果我按下该字母,则以给定的字母开头,如果没有以该字母开头的有效名称,则保持空白。< / p>

另一个相关问题是,使用上述自动完成时不会触发ComboboxSelected绑定:

self.combo1.bind("<<ComboboxSelected>>", self.selected)
当您使用常用方法(单击下拉列表或按向上/向下箭头)选择时,

将触发self.selected,但在您获得自动完成时则不会。

0 个答案:

没有答案