The ComboBox replaces the
OptionMenu with a powerful widget that uses a
TreeModel (usually a
ListStore) to provide the list items to display. The
ComboBox implements the
CellLayout interface that provides a number of
methods for managing the display of the list items. One or more
CellRenderers can be packed into a
ComboBox to customize the list item display.
The easy way to create and populate a
ComboBox is to use the convenience function:
combobox = gtk.combo_box_new_text()
This function creates a ComboBox and its
associated ListStore and packs it with a
CellRendererText. The following convenience methods
are used to populate or remove the contents of the
ComboBox and its
ListStore:
combobox.append_text(text) combobox.prepend_text(text) combobox.insert_text(position,text) combobox.remove_text(position)
where text is the string to be added to the
ComboBox and position is the
index where text is to be inserted or removed. In
most cases the convenience function and methods are all you need.
The example program comboboxbasic.py demonstrates the use of the above function and methods. Figure 16.5, “Basic ComboBox” illustrates the program in operation:
The active text can be retrieved using the method:
text = combobox.get_active_text()
Prior to version 2.6, the GTK+ developers
did not provide such a convenience method to retrieve the active text,
so you'd have to create your own implementation, similar to:
def get_active_text(combobox):
model = combobox.get_model()
active = combobox.get_active()
if active < 0:
return None
return model[active][0]
The index of the active item is retrieved using the method:
active = combobox.get_active()
The active item can be set using the method:
combobox.set_active(index)
where index is an integer larger than
-2. If index is -1 there is no active item and the
ComboBox display will be blank. If index is less than
-1, the call will be ignored. If index is greater
than -1 the list item with that index value will be displayed.
You can connect to the "changed" signal of a
ComboBox to be notified when the active item has been
changed. The signature of the "changed" handler is:
def changed_cb(combobox, ...):
where ... represents the zero or more
arguments passed to the GObject.connect()
method.
Creating a ComboBox using the
gtk.combo_box_new_text() function is roughly
equivalent to the following code:
liststore = gtk.ListStore(str) combobox = gtk.ComboBox(liststore) cell = gtk.CellRendererText() combobox.pack_start(cell, True) combobox.add_attribute(cell, 'text', 0)
To make use of the power of the various
TreeModel and CellRenderer
objects you need to construct a ComboBox using the
constructor:
combobox = gtk.ComboBox(model=None)
where model is a
TreeModel. If you create a
ComboBox without associating a
TreeModel, you can add one later using the
method:
combobox.set_model(model)
The associated TreeModel can be retrieved
using the method:
model = combobox.get_model()
Some of the things you can do with a
ComboBox are:
TreeModel with
other ComboBoxes and
TreeViews.ComboBox list items.TreeStore or
ListStore as the model for the
ComboBox list items.TreeModelSort to provide a
sorted ComboBox list.TreeModelFilter to use a
subtree of a TreeStore as the source for a
ComboBox list items.TreeModelFilter to use a
subset of the rows in a TreeStore or
ListStore as the ComboBox list
items.The use of the TreeModel and
CellRenderer objects is detailed in Chapter 14, Tree View Widget.
The ComboBox list items can be displayed
in a grid if you have a large number of items to display. Otherwise the list
will have scroll arrows if the entire list cannot be displayed. The
following method is used to set the number of columns to display:
combobox.set_wrap_width(width)
where width is the number of columns of
the grid displaying the list items. For example, the comboboxwrap.py program displays a
list of 50 items in 5 columns. Figure 16.6, “ComboBox with Wrapped Layout”
illustrates the program in operation:
With a large number of items, say more than 50, the use of the
set_wrap_width() method will have poor performance
because of the computation for the grid layout. To get a feel for the affect
modify the comboboxwrap.py
program line 18 to display 150 items.
for n in range(150):
Run the program and get a time estimate for startup. Then modify it by commenting out line 17:
#combobox.set_wrap_width(5)
Run and time it again. It should start up significantly faster. My experience is about 20 times faster.
In addition to the get_active() method
described above, you can retrieve a TreeIter pointing
at the active row by using the method:
iter = combobox.get_active_iter()
You can also set the active list item using a
TreeIter with the method:
combobox.set_active_iter(iter)
The set_row_span_column() and
set_column_span_column() methods are supposed to
allow the specification of a TreeModel column number
that contains the number of rows or columns that the list item is supposed
to span in a grid layout. Unfortunately, in GTK+ 2.4 these methods are
broken.
Since the ComboBox implements the
CellLayout interface which has similar capabilities
as the TreeViewColumn (see Section 14.5, “TreeViewColumns” for more information). Briefly, the
interface provides:
combobox.pack_start(cell,expand=True) combobox.pack_end(cell,expand=True) combobox.clear()
The first two methods pack a CellRenderer
into the ComboBox and the
clear() method clears all attributes from all
CellRenderers.
The following methods:
comboboxentry.add_attribute(cell,attribute,column) comboboxentry.set_attributes(cell,...)
set attributes for the CellRenderer
specified by cell. The
add_attribute() method takes a string
attribute name (e.g. 'text') and an integer
column number of the column in the
TreeModel to use to set
attribute. The additional arguments to the
set_attributes() method are
attribute=column pairs (e.g text=1).
The ComboBoxEntry widget replaces the
Combo widget. It is subclassed from the
ComboBox widget and contains a child
Entry widget that has its contents set by selecting
an item in the dropdown list or by direct text entry either from the
keyboard or by pasting from a Clipboard or a
selection.
Like the ComboBox, the
ComboBoxEntry can be created using the convenience
function:
comboboxentry = gtk.combo_box_entry_new_text()
The ComboBoxEntry should be populated
using the ComboBox convenience methods described in
Section 16.2.1.1, “Basic ComboBox Use”.
Since a ComboBoxEntry widget is a
Bin widget its child Entry
widget is available using the "child" attribute or the
get_child() method:
entry = comboboxentry.child entry = comboboxentry.get_child()
You can retrieve the Entry text using its
get_text() method.
Like the ComboBox, you can track changes
in the active list item by connecting to the "changed"
signal. Unfortunately, this doesn't help track changes to the text in the
Entry child that are direct entry. When a direct
entry is made to the child Entry widget the "changed"
signal will be emitted but the index returned by the
get_active() method will be -1. To track all
changes to the Entry text, you'll have to use the
Entry "changed" signal. For example:
def changed_cb(entry):
print entry.get_text()
comboboxentry.child.connect('changed', changed_cb)
will print out the text after every change in the child
Entry widget. For example, the comboboxentrybasic.py program
demonstrates the use of the convenience API. Figure 16.7, “Basic ComboBoxEntry” illustrates the program in
operation:
Note that when the Entry text is changed
due to the selection of a dropdown list item the "changed" handler is called
twice: once when the text is cleared; and, once when the text is set with
the selected list item text.
The constructor for a ComboBoxEntry is:
comboboxentry = gtk.ComboBoxEntry(model=None,column=-1)
where model is a
TreeModel and column is the
number of the column in model to use for setting the
list items. If column is not specified the default value is -1 which means
the text column is unset.
Creating a ComboBoxEntry using the
convenience function gtk.combo_box_entry_new_text() is
equivalent to the following:
liststore = gtk.ListStore(str) comboboxentry = gtk.ComboBoxEntry(liststore, 0)
The ComboBoxEntry adds a couple of
methods that are used to set and retrieve the
TreeModel column number to use for setting the list
item strings:
comboboxentry.set_text_column(text_column)
text_column = comboboxentry.get_text_column()
The text column can also be retrieved and set using the
"text-column" property. See Section 16.2.1.2, “Advanced ComboBox Use” for
more information on the advanced use of the
ComboBoxEntry.
Your application must set the text column for the
ComboBoxEntry to set the Entry
contents from the dropdown list. The text column can only be set once,
either by using the constructor or by using the
set_text_column() method.
When a ComboBoxEntry is created it is
packed with a new CellRendererText which is not
accessible. The 'text' attribute for the
CellRendererText has to be set as a side effect of
setting the text column using the set_text_column()
method. You can pack additional CellRenderers into a
ComboBoxEntry for display in the dropdown list. See
Section 16.2.1.2, “Advanced ComboBox Use” for more information.