Gtk.ComboBox
继承关系
Gtk.ComboBox组合框,用多个待选择项来填充其内容。
Gtk.ComboBox是Gtk.Bin的直接子类
Methods
方法修饰词 | 方法名及参数 |
---|---|
static | new () |
static | new_with_area (area) |
static | new_with_area_and_entry (area) |
static | new_with_entry () |
static | new_with_model (model) |
static | new_with_model_and_entry (model) |
get_active () | |
get_active_id () | |
get_active_iter () | |
get_add_tearoffs () | |
get_button_sensitivity () | |
get_column_span_column () | |
get_entry_text_column () | |
get_focus_on_click () | |
get_has_entry () | |
get_id_column () | |
get_model () | |
get_popup_accessible () | |
get_popup_fixed_width () | |
get_row_span_column () | |
get_title () | |
get_wrap_width () | |
popdown () | |
popup () | |
popup_for_device (device) | |
set_active (index_) | |
set_active_id (active_id) | |
set_active_iter (iter) | |
set_add_tearoffs (add_tearoffs) | |
set_button_sensitivity (sensitivity) | |
set_column_span_column (column_span) | |
set_entry_text_column (text_column) | |
set_focus_on_click (focus_on_click) | |
set_id_column (id_column) | |
set_model (model) | |
set_popup_fixed_width (fixed) | |
set_row_separator_func (func, *data) | |
set_row_span_column (row_span) | |
set_title (title) | |
set_wrap_width (width) |
Virtual Methods
do_changed () |
do_format_entry_text (path) |
Properties
Name | Type | Flags | Short Description |
---|---|---|---|
active | int | r/w/en | 当前选中项的索引 |
active-id | str | r/w/en | 当前选中项的文本内容 |
add-tearoffs | bool | d/r/w/en | Whether dropdowns should have a tearoff menu item deprecated |
button-sensitivity | Gtk.SensitivityType | r/w/en | 当model为空时,下拉菜单是否可点击。默认不可点击 |
cell-area | Gtk.CellArea | r/w/co | The Gtk.CellArea used to layout cells |
column-span-column | int | r/w/en | TreeModel column containing the column span values |
entry-text-column | int | r/w/en | 如果Gtk.ComboBox创建的时候has-entry属性True,指定model中哪一列显示在entry的文本中 |
has-entry | bool | r/w/co | ComboBox 是否带有Gtk.Entry |
has-frame | bool | r/w/en | 是否在孩子的外围显示一个Frame |
id-column | int | r/w/en | 指定显示model中的哪一列 |
model | Gtk.TreeModel | r/w/en | ComboBox的数据源model |
popup-fixed-width | bool | r/w/en | Whether the popup’s width should be a fixed width matching the allocated width of the combo box |
popup-shown | bool | r | Whether the combo’s dropdown is shown |
row-span-column | int | r/w/en | TreeModel column containing the row span values |
tearoff-title | str | d/r/w/en | A title that may be displayed by the window manager when the popup is torn-off deprecated |
wrap-width | int | r/w/en | Wrap width for laying out the items in a grid |
Signals
Name | Short Description |
---|---|
changed | 选中项改变时发送此信号. |
format-entry-text | For combo boxes that are created with an entry (See Gtk.ComboBox :has-entry). |
move-active | The ::move-active signal is a keybinding signal which gets emitted to move the active selection. |
popdown | The ::popdown signal is a keybinding signal which gets emitted to popdown the combo box list. |
popup | The ::popup signal is a keybinding signal which gets emitted to popup the combo box list. |
例子
一
代码:
#!/usr/bin/env python3
# Created by xiaosanyu at 16/6/15
# section 021
TITLE = "ComboBox"
DESCRIPTION = """
A Gtk.ComboBox is a widget that allows the user to choose from a list of valid choices
"""
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class ComboBoxWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="ComboBox Example")
self.set_border_width(10)
name_store = Gtk.ListStore(int, str)
name_store.append([1, "Billy Bob"])
name_store.append([11, "Billy Bob Junior"])
name_store.append([12, "Sue Bob"])
name_store.append([2, "Joey Jojo"])
name_store.append([3, "Rob McRoberts"])
name_store.append([31, "Xavier McRoberts"])
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
name_combo = Gtk.ComboBox.new_with_model_and_entry(name_store)
name_combo.connect("changed", self.on_name_combo_changed)
name_combo.set_entry_text_column(1)
vbox.pack_start(name_combo, False, False, 0)
country_store = Gtk.ListStore(str)
countries = ["Austria", "Brazil", "Belgium", "France", "Germany",
"Switzerland", "United Kingdom", "United States of America",
"Uruguay"]
for country in countries:
country_store.append([country])
country_combo = Gtk.ComboBox.new_with_model(country_store)
country_combo.connect("changed", self.on_country_combo_changed)
renderer_text = Gtk.CellRendererText()
country_combo.pack_start(renderer_text, True)
country_combo.add_attribute(renderer_text, "text", 0)
vbox.pack_start(country_combo, False, False, True)
currencies = ["Euro", "US Dollars", "British Pound", "Japanese Yen",
"Russian Ruble", "Mexican peso", "Swiss franc"]
currency_combo = Gtk.ComboBoxText()
currency_combo.set_entry_text_column(0)
currency_combo.connect("changed", self.on_currency_combo_changed)
for currency in currencies:
currency_combo.append_text(currency)
vbox.pack_start(currency_combo, False, False, 0)
self.add(vbox)
@staticmethod
def on_name_combo_changed(combo):
tree_iter = combo.get_active_iter()
if tree_iter is not None:
model = combo.get_model()
row_id, name = model[tree_iter][:2]
print("Selected: ID=%d, name=%s" % (row_id, name))
else:
entry = combo.get_child()
print("Entered: %s" % entry.get_text())
@staticmethod
def on_country_combo_changed(combo):
tree_iter = combo.get_active_iter()
if tree_iter is not None:
model = combo.get_model()
country = model[tree_iter][0]
print("Selected: country=%s" % country)
@staticmethod
def on_currency_combo_changed(combo):
text = combo.get_active_text()
if text is not None:
print("Selected: currency=%s" % text)
def main():
win = ComboBoxWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
if __name__ == "__main__":
main()
代码解析:
name_store = Gtk.ListStore(int, str)
name_store.append([1, "Billy Bob"])
name_store.append([11, "Billy Bob Junior"])
name_store.append([12, "Sue Bob"])
name_store.append([2, "Joey Jojo"])
name_store.append([3, "Rob McRoberts"])
name_store.append([31, "Xavier McRoberts"])
创建第一个Gtk.ListStore,第一列为int类型,第二列为str类型
然后插入6行数据
name_combo = Gtk.ComboBox.new_with_model_and_entry(name_store)
使用前面创建的Gtk.ListStore作为数据源(model)来创建一个Gtk.ComboBox,并且它带有一个可供输入内容的Gtk.Entry
name_combo.connect("changed",self.on_name_combo_changed)
绑定”changed”信号到on_name_combo_changed()方法
@staticmethod
def on_name_combo_changed(combo):
tree_iter = combo.get_active_iter()
if tree_iter is not None:
model = combo.get_model()
row_id, name = model[tree_iter][:2]
print("Selected: ID=%d, name=%s" % (row_id, name))
else:
entry = combo.get_child()
print("Entered: %s" % entry.get_text())
当entry中的内容有改变时,执行此方法,如果是选择ComboBox中的内容则combo.get_active_iter()不为None,如果是手动输入内容则为None。
name_combo.set_entry_text_column(1)
设置Entry里面内容来自model中的第2列
country_store = Gtk.ListStore(str)
countries = ["Austria", "Brazil", "Belgium", "France", "Germany","Switzerland", "United Kingdom", "United States of America","Uruguay"]
for country in countries:
country_store.append([country])
创建第二个Gtk.ListStore,只有一列,为str类型
填充数据
country_combo = Gtk.ComboBox.new_with_model(country_store)
使用前面的ListStore作为model来创建第二个Gtk.ComboBox
country_combo.connect("changed",self.on_country_combo_changed)
绑定”changed”信号到self.on_country_combo_changed()方法
创建一个CellRendererText用来显示文本信息,将CellRendererText添加到ComboBox容器中,设置CellRendererText,其中的text使用model中的第1列来填充
renderer_text = Gtk.CellRendererText()
country_combo.pack_start(renderer_text, True)
country_combo.add_attribute(renderer_text, "text", 0)
如果ComboBox只有一个str列,则可以使用它的子类ComboBoxText来简化创建过程
currencies = ["Euro", "US Dollars", "British Pound", "Japanese Yen","Russian Ruble", "Mexican peso", "Swiss franc"]
currency_combo = Gtk.ComboBoxText()
currency_combo.set_entry_text_column(0)
currency_combo.connect("changed", self.on_currency_combo_changed)
for currency in currencies:
currency_combo.append_text(currency)
二
代码:
#!/usr/bin/env python3
# section 022
TITLE = "Combo boxes"
DESCRIPTION = """
The ComboBox widget allows to select one option out of a list.
The ComboBoxEntry additionally allows the user to enter a value
that is not in the list of options.
How the options are displayed is controlled by cell renderers.
"""
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkPixbuf, GLib, GObject
(PIXBUF_COL, TEXT_COL) = range(2)
class MaskEntry(Gtk.Entry):
__gtype_name__ = 'MaskEntry'
def __init__(self, mask=None):
self.mask = mask
super(MaskEntry, self).__init__()
self.connect('changed', self.changed_cb)
self.error_color = Gdk.RGBA()
self.error_color.red = 1.0
self.error_color.green = 0.9
self.error_color_blue = 0.9
self.error_color.alpha = 1.0
# workaround since override_color doesn't accept None yet
style_ctx = self.get_style_context()
self.normal_color = style_ctx.get_color(0)
def set_background(self):
if self.mask:
if not GLib.regex_match_simple(self.mask,
self.get_text(), 0, 0):
self.override_color(0, self.error_color)
return
self.override_color(0, self.normal_color)
def changed_cb(self, entry):
self.set_background()
class ComboboxApp:
def __init__(self, demoapp):
self.demoapp = demoapp
self.window = Gtk.Window()
self.window.set_title('Combo boxes')
self.window.set_border_width(10)
self.window.connect('destroy', lambda w: Gtk.main_quit())
vbox = Gtk.VBox(homogeneous=False, spacing=2)
self.window.add(vbox)
frame = Gtk.Frame(label='Some stock icons')
vbox.pack_start(frame, False, False, 0)
box = Gtk.VBox(homogeneous=False, spacing=0)
box.set_border_width(5)
frame.add(box)
model = self.create_stock_icon_store()
combo = Gtk.ComboBox(model=model)
box.add(combo)
renderer = Gtk.CellRendererPixbuf()
combo.pack_start(renderer, False)
# FIXME: override set_attributes
combo.add_attribute(renderer, 'pixbuf', PIXBUF_COL)
combo.set_cell_data_func(renderer, self.set_sensitive, None)
renderer = Gtk.CellRendererText()
combo.pack_start(renderer, True)
combo.add_attribute(renderer, 'text', TEXT_COL)
combo.set_cell_data_func(renderer, self.set_sensitive, None)
combo.set_row_separator_func(self.is_separator, None)
combo.set_active(0)
# a combobox demonstrating trees
frame = Gtk.Frame(label='Where are we ?')
vbox.pack_start(frame, False, False, 0)
box = Gtk.VBox(homogeneous=False, spacing=0)
box.set_border_width(5)
frame.add(box)
model = self.create_capital_store()
combo = Gtk.ComboBox(model=model)
box.add(combo)
renderer = Gtk.CellRendererText()
combo.pack_start(renderer, True)
combo.add_attribute(renderer, 'text', 0)
combo.set_cell_data_func(renderer, self.is_capital_sensistive, None)
# FIXME: make new_from_indices work
# make constructor take list or string of indices
path = Gtk.TreePath.new_from_string('0:8')
treeiter = model.get_iter(path)
combo.set_active_iter(treeiter)
# A GtkComboBoxEntry with validation.
frame = Gtk.Frame(label='Editable')
vbox.pack_start(frame, False, False, 0)
box = Gtk.VBox(homogeneous=False, spacing=0)
box.set_border_width(5)
frame.add(box)
combo = Gtk.ComboBoxText.new_with_entry()
self.fill_combo_entry(combo)
box.add(combo)
entry = MaskEntry(mask='^([0-9]*|One|Two|2\302\275|Three)$')
combo.get_child().destroy()
combo.add(entry)
# A combobox with string IDs
frame = Gtk.Frame(label='String IDs')
vbox.pack_start(frame, False, False, 0)
box = Gtk.VBox(homogeneous=False, spacing=0)
box.set_border_width(5)
frame.add(box)
# FIXME: model is not setup when constructing Gtk.ComboBoxText()
# so we call new() - Gtk should fix this to setup the model
# in __init__, not in the constructor
combo = Gtk.ComboBoxText.new()
combo.append('never', 'Not visible')
combo.append('when-active', 'Visible when active')
combo.append('always', 'Always visible')
box.add(combo)
entry = Gtk.Entry()
combo.bind_property('active-id',
entry, 'text',
GObject.BindingFlags.BIDIRECTIONAL)
box.add(entry)
self.window.show_all()
def strip_underscore(self, s):
return s.replace('_', '')
def create_stock_icon_store(self):
stock_id = (Gtk.STOCK_DIALOG_WARNING,
Gtk.STOCK_STOP,
Gtk.STOCK_NEW,
Gtk.STOCK_CLEAR,
None,
Gtk.STOCK_OPEN)
cellview = Gtk.CellView()
store = Gtk.ListStore(GdkPixbuf.Pixbuf, str)
for id in stock_id:
if id is not None:
pixbuf = cellview.render_icon(id, Gtk.IconSize.BUTTON, None)
item = Gtk.stock_lookup(id)
label = self.strip_underscore(item.label)
store.append((pixbuf, label))
else:
store.append((None, 'separator'))
return store
def set_sensitive(self, cell_layout, cell, tree_model, treeiter, data):
"""
A GtkCellLayoutDataFunc that demonstrates how one can control
sensitivity of rows. This particular function does nothing
useful and just makes the second row insensitive.
"""
path = tree_model.get_path(treeiter)
indices = path.get_indices()
sensitive = not (indices[0] == 1)
cell.set_property('sensitive', sensitive)
def is_separator(self, model, treeiter, data):
"""
A GtkTreeViewRowSeparatorFunc that demonstrates how rows can be
rendered as separators. This particular function does nothing
useful and just turns the fourth row into a separator.
"""
path = model.get_path(treeiter)
indices = path.get_indices()
result = (indices[0] == 4)
return result
def create_capital_store(self):
capitals = (
{'group': 'A - B', 'capital': None},
{'group': None, 'capital': 'Albany'},
{'group': None, 'capital': 'Annapolis'},
{'group': None, 'capital': 'Atlanta'},
{'group': None, 'capital': 'Augusta'},
{'group': None, 'capital': 'Austin'},
{'group': None, 'capital': 'Baton Rouge'},
{'group': None, 'capital': 'Bismarck'},
{'group': None, 'capital': 'Boise'},
{'group': None, 'capital': 'Boston'},
{'group': 'C - D', 'capital': None},
{'group': None, 'capital': 'Carson City'},
{'group': None, 'capital': 'Charleston'},
{'group': None, 'capital': 'Cheyeene'},
{'group': None, 'capital': 'Columbia'},
{'group': None, 'capital': 'Columbus'},
{'group': None, 'capital': 'Concord'},
{'group': None, 'capital': 'Denver'},
{'group': None, 'capital': 'Des Moines'},
{'group': None, 'capital': 'Dover'},
{'group': 'E - J', 'capital': None},
{'group': None, 'capital': 'Frankfort'},
{'group': None, 'capital': 'Harrisburg'},
{'group': None, 'capital': 'Hartford'},
{'group': None, 'capital': 'Helena'},
{'group': None, 'capital': 'Honolulu'},
{'group': None, 'capital': 'Indianapolis'},
{'group': None, 'capital': 'Jackson'},
{'group': None, 'capital': 'Jefferson City'},
{'group': None, 'capital': 'Juneau'},
{'group': 'K - O', 'capital': None},
{'group': None, 'capital': 'Lansing'},
{'group': None, 'capital': 'Lincon'},
{'group': None, 'capital': 'Little Rock'},
{'group': None, 'capital': 'Madison'},
{'group': None, 'capital': 'Montgomery'},
{'group': None, 'capital': 'Montpelier'},
{'group': None, 'capital': 'Nashville'},
{'group': None, 'capital': 'Oklahoma City'},
{'group': None, 'capital': 'Olympia'},
{'group': 'P - S', 'capital': None},
{'group': None, 'capital': 'Phoenix'},
{'group': None, 'capital': 'Pierre'},
{'group': None, 'capital': 'Providence'},
{'group': None, 'capital': 'Raleigh'},
{'group': None, 'capital': 'Richmond'},
{'group': None, 'capital': 'Sacramento'},
{'group': None, 'capital': 'Salem'},
{'group': None, 'capital': 'Salt Lake City'},
{'group': None, 'capital': 'Santa Fe'},
{'group': None, 'capital': 'Springfield'},
{'group': None, 'capital': 'St. Paul'},
{'group': 'T - Z', 'capital': None},
{'group': None, 'capital': 'Tallahassee'},
{'group': None, 'capital': 'Topeka'},
{'group': None, 'capital': 'Trenton'}
)
parent = None
store = Gtk.TreeStore(str)
for item in capitals:
if item['group']:
parent = store.append(None, (item['group'],))
elif item['capital']:
store.append(parent, (item['capital'],))
return store
def is_capital_sensistive(self, cell_layout, cell, tree_model, treeiter, data):
sensitive = not tree_model.iter_has_child(treeiter)
cell.set_property('sensitive', sensitive)
def fill_combo_entry(self, entry):
entry.append_text('One')
entry.append_text('Two')
entry.append_text('2\302\275')
entry.append_text('Three')
def main(demoapp=None):
ComboboxApp(demoapp)
Gtk.main()
if __name__ == '__main__':
main()
代码解析:
创建第一个ListStore,第一列为图片,第二列为文本
model = self.create_stock_icon_store()
def create_stock_icon_store(self):
stock_id = (Gtk.STOCK_DIALOG_WARNING,
Gtk.STOCK_STOP,
Gtk.STOCK_NEW,
Gtk.STOCK_CLEAR,
None,
Gtk.STOCK_OPEN)
cellview = Gtk.CellView()
store = Gtk.ListStore(GdkPixbuf.Pixbuf, str)
for id in stock_id:
if id is not None:
pixbuf = cellview.render_icon(id, Gtk.IconSize.BUTTON, None)
item = Gtk.stock_lookup(id)
label = self.strip_underscore(item.label)
store.append((pixbuf, label))
else:
store.append((None, 'separator'))
return store
使用这个model创建第一个ComboBox
combo = Gtk.ComboBox(model=model)
创建CellRendererPixbuf,作为ComboBox的第一列
renderer = Gtk.CellRendererPixbuf()
combo.pack_start(renderer, False)
combo.add_attribute(renderer, 'pixbuf', PIXBUF_COL)
创建CellRendererText,作为ComboBox的第二列
renderer = Gtk.CellRendererText()
combo.pack_start(renderer, True)
combo.add_attribute(renderer, 'text', TEXT_COL)
给每个单元格添加一个方法。如果是第二行(索引号为1)的单元格,则这个单元格不激活,不可点击
combo.set_cell_data_func(renderer, self.set_sensitive, None)
def set_sensitive(self, cell_layout, cell, tree_model, treeiter, data):
path = tree_model.get_path(treeiter)
indices = path.get_indices()
sensitive = not (indices[0] == 1)
cell.set_property('sensitive', sensitive)
设置行分割函数。如果是第五行(索引号为4),则添加分隔线
combo.set_row_separator_func(self.is_separator, None)
def is_separator(self, model, treeiter, data):
path = model.get_path(treeiter)
indices = path.get_indices()
result = (indices[0] == 4)
return result
选中第1行
combo.set_active(0)
用所给列表,创建第二个ListStore,只有一个str列,但是分层次
model = self.create_capital_store()
parent = None
store = Gtk.TreeStore(str)
for item in capitals:
if item['group']:
parent = store.append(None, (item['group'],))
elif item['capital']:
store.append(parent, (item['capital'],))
return store
以所给model创建第二个ComboBox
combo = Gtk.ComboBox(model=model)
renderer = Gtk.CellRendererText()
combo.pack_start(renderer, True)
combo.add_attribute(renderer, 'text', 0)
给每列数据添加方法,如果该列没有子项,则不可点击
combo.set_cell_data_func(renderer,self.is_capital_sensistive, None)
def is_capital_sensistive(self, cell_layout, cell, tree_model, treeiter, data):
sensitive = not tree_model.iter_has_child(treeiter)
cell.set_property('sensitive', sensitive)
选中第1到9行
path = Gtk.TreePath.new_from_string('0:8')
treeiter = model.get_iter(path)
combo.set_active_iter(treeiter)
创建第三个ComboBox,带有一个输入框
combo = Gtk.ComboBoxText.new_with_entry()
填充数据
self.fill_combo_entry(combo)
def fill_combo_entry(self, entry):
entry.append_text('One')
entry.append_text('Two')
entry.append_text('2\302\275')
entry.append_text('Three')
移除ComboBoxText自带的entry,使用自定义的entry代替.自定义entry功能就是检测输入内容,如果不是给定的几个值文字显示为红色,如果是,显示为正常黑色。
entry = MaskEntry(mask='^([0-9]*|One|Two|2\302\275|Three)$')
Gtk.Container.remove(combo, combo.get_child())
combo.add(entry)
创建第四个ComboBox
combo = Gtk.ComboBoxText.new()
combo.append('never', 'Not visible')
combo.append('when-active', 'Visible when active')
combo.append('always', 'Always visible')
创建一个entry
entry = Gtk.Entry()
将ComboBox的’active-id’属性和entry的’text’绑定起来。
‘active-id’属性就是ComboBox当前选中行的内容,
这句话的意思就是将ComboBox当前选中行的内容填充到entry中
combo.bind_property('active-id',
entry, 'text',
GObject.BindingFlags.BIDIRECTIONAL)
附录
Gtk.SensitivityType
class Gtk.SensitivityType
Bases: GObject.GEnum
当model为空时,下拉框是否可点击
AUTO = 0
自动,有数据可点击,没数据不可点击
ON = 1
可点击
OFF = 2
不可点击
代码下载地址:http://download.csdn.net/detail/a87b01c14/9594728