Python ttk.combobox принудительно опубликовать/открыть

Я пытаюсь расширить класс combobox ttk, чтобы разрешить самовнушение. код, который у меня есть, работает хорошо, но я хотел бы, чтобы он отображал раскрывающийся список после ввода некоторого текста, не удаляя фокус из вводной части виджета.

Часть, с которой я борюсь, - это найти способ заставить выпадающий список, в документах python я не могу найти упоминания об этом, однако в документах tk я нашел метод post, который, как мне кажется, должен это делать, за исключением того, что он не похоже, он реализован в оболочке python.

Я также попытался сгенерировать событие клавиши со стрелкой вниз после того, как автозаполнение произошло, однако, хотя это действительно показывает раскрывающийся список, он удаляет фокус, и попытка установить фокус после этого события, похоже, тоже не работает (фокус не возвращается)

Кто-нибудь знает о функции, которую я могу использовать для достижения этой цели?

У меня есть код для python 3.3, использующий только стандартные библиотеки:

class AutoCombobox(ttk.Combobox):
    def __init__(self, parent, **options):
        ttk.Combobox.__init__(self, parent, **options)
        self.bind("<KeyRelease>", self.AutoComplete_1)
        self.bind("<<ComboboxSelected>>", self.Cancel_Autocomplete)
        self.bind("<Return>", self.Cancel_Autocomplete)
        self.autoid = None

    def Cancel_Autocomplete(self, event=None):
        self.after_cancel(self.autoid) 

    def AutoComplete_1(self, event):
        if self.autoid != None:
            self.after_cancel(self.autoid)
        if event.keysym in ["BackSpace", "Delete", "Return"]:
            return
        self.autoid = self.after(200, self.AutoComplete_2)

    def AutoComplete_2(self):
        data = self.get()
        if data != "":
            for entry in self["values"]:
                match = True
                try:
                    for index in range(0, len(data)):
                        if data[index] != entry[index]:
                            match = False
                            break
                except IndexError:
                    match = False
                if match == True:
                    self.set(entry)
                    self.selection_range(len(data), "end")
                    self.event_generate("<Down>",when="tail")
                    self.focus_set()
                    break
            self.autoid = None

person James Kent    schedule 31.08.2014    source источник
comment
Вы можете вызвать post, но это не решит вашу проблему, потому что post создает новый раскрывающийся список и удаляет его, когда он теряет фокус/нажатие клавиши esc: self.tk.call('ttk::combobox::Post', self)   -  person falsetru    schedule 31.08.2014
comment
Я предполагаю, что тогда это означает, что единственный способ добиться того, что мне нужно, - это создать свой собственный мега-виджет из набора записей, списка и кнопок во фрейме, позор действительно, поскольку остальная часть моего кода была так много проще, чем все примеры автозаполнения выпадающего списка, которые я мог найти. хотя я не смог найти тот, который действительно показывал раскрывающийся список при наборе текста. хотя спасибо за помощь.   -  person James Kent    schedule 31.08.2014
comment
@JamesKent Я пытаюсь сделать что-то подобное, вам удалось найти решение?   -  person The Beanstalk    schedule 20.04.2016
comment
не повезло с надежным форсированием раскрывающегося списка, однако остальная часть автозаполнения работала достаточно хорошо.   -  person James Kent    schedule 22.04.2016


Ответы (1)


Вам не нужно наследовать ttk.Combobox для этого события; просто используйте event_generate, чтобы вызвать раскрывающийся список:

box = Combobox(...)
def callback(box):
    box.event_generate('<Down>')
person Jun    schedule 07.03.2015
comment
Это решение убирает фокус с текстовой записи виджета со списком, что является исходной проблемой OP. - person toxicantidote; 22.01.2021