python Tix - how to clear a combobox

4.7k views Asked by At

how do I clear all the items in a Tix.ComboBox object? I tried things like

cb.entry.delete (0, Tix.END)

and other veriations of this function but it doesn't seem to do anything. also its not clear from the API which function I should use and the doc I've read say nothing about it. is it even possible??

thanks!

EDIT: PS deleting item by name will also be great. couldn't find how to do that either.

1

There are 1 answers

5
abarnert On BEST ANSWER

As the docs say, a ComboBox has an entry subwidget, and a listbox subwidget. See the Wikipedia page on combo boxes in general: the Something else part is the entry, and the List item 1 etc. parts are the listbox.

So, cb.entry.delete is perfectly valid, but it's deleting the contents of the entry subwidget. That doesn't affect any of the items in the listbox.


So, how do you get the listbox? Well, in Tcl/Tk, you can just access cb.listbox. But that doesn't work in Python/Tkinter.

If you look at the source, you can see that ComboBox doesn't have two sub-widgets, but five, none of which is a Listbox or named listbox:

entry       Entry
arrow       Button
slistbox    ScrolledListBox
tick        Button
cross       Button : present if created with the fancy option

(You should be able to see this easily with help(Tix.ComboBox) in your interactive interpreter.)

But ScrolledListBox itself is another Tix composite widget, without anything useful on its own, so you still need to find the Listbox sub-sub-widget. Look at the help or source and it'll show you that ScrolledListBox has a listbox. Fortunately, that really is a Listbox (well, a _dummyListbox, but that's just a Listbox subclass that knows how to be a Tix subwidget).

So, what you really want is cb.slistbox.listbox.

(I believe that Tcl/Tk forwards along attribute references, while Python/Tkinter doesn't, which is why Tix and other fancy Tk wrappers and extensions aren't as nice to use from Python as the Tk docs make them appear.)


Note that, as the docs for ListBox say, 0 refers to the first entry, and END to the last entry, so the arguments in your call are correct.

So, long story short, this should do it:

cb.slistbox.listbox.delete(0, Tix.END)

And you should know how to find similar cases in the future. (Assuming you're not so traumatized by Tix that you avoid it completely.)


Meanwhile, as far as I know, there's no way to delete by name, but it's not that hard to do yourself. Just iterate the entries and check them:

for i in range(cb.slistbox.listbox.size()):
    if cb.slistbox.listbox.get(i) == name:
        cb.slistbox.listbox.delete(i)
        break