Is it possible to make Combobox editable while dropdown is opened? I haven't found any solution. I want to make it more like Google Search but using ComboBox.
-
Thanks @stovfl: But I'm not searching for auto completion. I just want to type anything in combobox while dropdown is opened. Rightnow as long as dropdown is open, we are not able to write anything. My question is, can we able to make combobox editable while dropdown opended? means dropdown will open when we type anything in the combobox and we are still able to type even after dropdown is opened. – KK. Jan 17 '20 at 09:14
-
***"type in `Entry` while `Listbox` is opened"***: That's out of scope for `Combobox`. You can show the `Listbox` by send `.event_generate('
')` but then the `Entry` loose the `Focus`. If you `Focus` the `Entry` the `Listbox` get closed. Use something like this: [making-a-pop-up-keyboard-in-tkinter-with-toplevel](https://stackoverflow.com/questions/22894937) – stovfl Jan 17 '20 at 10:20 -
Is there any way to bind "Up Button" so that while pressing "Up Button" dropdown will close and focus will back to ComboBox Entry? Usually by pressing "Up Button" main_focus changes from one data to another data but stops at the top of the dropdown, Is there any way to close dropdown if we again press "Up Button" then focus automatically come back to entry? – KK. Jan 17 '20 at 11:02
-
1***bind "Up Button"***: Unknow, these [Events](http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm) are available. – stovfl Jan 17 '20 at 11:21
-
Is there any way to close already opened dropdown of combobox by pressing any buttons(Not automatically)? – KK. Jan 17 '20 at 12:45
-
1***"by pressing any buttons"***: You are talking about `Button` but you mean `Keyboard Arrow Key`?? – stovfl Jan 17 '20 at 13:58
-
Sorry for confusion. Yes I mean Arrow Key, It's not working when Dropdown openes. I just want whenever focus at the top of the dropdown list, then by pressing "Up arrow key" focus return to editing mode(ComboBox Entry). Is it possible? we don't have any knowledge about dropdown frame since it's comes from internal functions. If we some how know the frame then we might get some ideas to close dropdown accords to our use... – KK. Jan 20 '20 at 05:28
-
Relevant [hide-and-show-ttk-combobox-dropdown-list](https://stackoverflow.com/questions/41666562/hide-and-show-ttk-combobox-dropdown-list) – stovfl Jan 22 '20 at 18:59
-
I just want to bind the after call **"source.after(delay, _source_delayed_clicked)"** with up arrow key, but seems like it's not possible because comboBox dropdown frame's coming from internally... – KK. Jan 24 '20 at 04:54
-
Related: https://stackoverflow.com/q/25588207/3372061 – Dev-iL Jan 18 '23 at 13:23
1 Answers
Question: Show
Combobox
PopdownWindow, while editing text
This example extends a ttk.Combobox
to the following:
- Show the PopdownWindow while typing
- Open the PopdownWindow on Key-pressed
'<Down>'
- Close the PopdownWindow on Key-pressed
'<Up'
, if at the first item in theListbox
Reference:
-
For each widget, you can bind Python functions and methods to events.
ttk::combobox
— text field with popdown selection listThe
ttk::combobox
uses theentry
andlistbox
widgets internally.
Inherit from
ttk.Combox
import tkinter as tk import tkinter.ttk as ttk class Combobox(ttk.Combobox):
Helper function, to map the internal
Toplevel
andListbox
to atkinter
object.WARNING: This uses
Tk/Tcl
internals, which could change without notice.
This may working only with the tested Tk/Tcl version!def _tk(self, cls, parent): obj = cls(parent) obj.destroy() if cls is tk.Toplevel: obj._w = self.tk.call('ttk::combobox::PopdownWindow', self) else: obj._w = '{}.{}'.format(parent._w, 'f.l') return obj
Initalize the object, get the internal references and bind to Key-press events
def __init__(self, parent, **kwargs): super().__init__(parent, **kwargs) self.popdown = self._tk(tk.Toplevel, parent) self.listbox = self._tk(tk.Listbox, self.popdown) self.bind("<KeyPress>", self.on_keypress, '+') self.listbox.bind("<Up>", self.on_keypress)
Key-pressed handler to show or hide the PopdownWindow and set the Keyboard focus.
def on_keypress(self, event): if event.widget == self: state = self.popdown.state() if state == 'withdrawn' \ and event.keysym not in ['BackSpace', 'Up']: self.event_generate('<Button-1>') self.after(0, self.focus_set) if event.keysym == 'Down': self.after(0, self.listbox.focus_set) else: # self.listbox curselection = self.listbox.curselection() if event.keysym == 'Up' and curselection[0] == 0: self.popdown.withdraw()
Usage:
class App(tk.Tk): def __init__(self): super().__init__() values = ('one', 'two', 'three', 'four', 'five', 'six', 'seven') self.cb = Combobox(self, value=values) self.cb.grid(row=0, column=0) if __name__ == "__main__": App().mainloop()
Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6

- 14,998
- 7
- 24
- 51
-
I'm not able to understand. Can you send me full code at once, it will be great help.Thanking You in advance. – KK. Feb 28 '20 at 06:34
-
-
1On my mac I had to set the delays in the two after methods to at least 20 ms. Lower than that and the focus wasn't reset to the Entry field. – Tls Chris Mar 21 '20 at 17:25
-
1@TlsChris ***"MACOS"*** behaves different in certain points using `tkinter`. You can try to replace with `.after_idle(self....` without a timeout value. – stovfl Mar 21 '20 at 20:14
-
Thanks for the suggestion. The focus still ended up on the popdown! For what I'm doing even a 100ms delay in `after` doesn't seem to be a problem. How many people can type 10 meaningful characters in a second? – Tls Chris Mar 22 '20 at 14:35
-
@TlsChris ***"even a 100ms delay in after doesn't seem to be a problem"***: Consens with this, it's a timing issue. You can't change the focus while the current callback has not finished. – stovfl Mar 22 '20 at 14:41
-
@stovfl, my combobox list is not updating with this solution. I am using **trace('w', on_field_change)** and then after list update, I'm doing **combobox['values'] = listVar** but it's not working. Please tell me what do we have to change in class **Combobox**? – KK. Apr 29 '20 at 05:24
-
@KK ***I am using `trace('w',`...***: This is the same as `.bind("
"`. Your `trace(...` break the `KeyPress` event. Try to add `on_field_change()` right after and inside `if event.widget == self:` – stovfl Apr 29 '20 at 07:47 -
@stovfl above solution is not working. Can you send a code which can modify combobox list as per the user_input? – KK. Apr 29 '20 at 13:16
-