使用valadoc上的drodown示例,我有一个下拉列表,显示每行两列数据。我正在寻找创建一个组合框,该组合框在选择值时显示两列,但在选择后隐藏第二列。我尝试了以下方法:
Gtk.ComboBox combo = new Gtk.ComboBox.with_model(list_store);
Gtk.CellRendererText name_renderer = new Gtk.CellRendererText();
combo.pack_start(name_renderer, true);
combo.add_attribute(name_renderer, "text", 0);
Gtk.CellRendererText shortcut_renderer = new Gtk.CellRendererText();
combo.pack_start(shortcut_renderer, true);
combo.add_attribute(shortcut_renderer, "text", 1);
combo.popup.connect(() => {
combo.add_attribute(shortcut_renderer, "text", 1);
});
combo.popdown.connect(() => {
combo.clear_attributes(shortcut_renderer);
return true;
});
但这给出了以下错误:
Gtk-CRITICAL **: 21:46:08.050: gtk_list_store_get_value: assertion 'column < priv->n_columns' failed
GLib-GObject-CRITICAL **: 21:46:08.050: g_value_transform: assertion 'G_IS_VALUE (src_value)' failed
这些错误使我认为我可能会以错误的方式前进,是否有人对如何实现这一目标有任何指示?
最佳答案
Gtk.ComboBox
信号popup
和popdown
是键绑定(bind)信号,这意味着它们将仅由键盘触发。这也意味着您所追求的行为没有简单的解决方案。可见性本身很容易。list_store
需要一个新的 bool(boolean) 类型列,该列将控制渲染器的可见性:
Gtk.ListStore list_store = new Gtk.ListStore (3, typeof (string), typeof (int), typeof (bool));
然后,将visible属性添加到要隐藏的渲染器中:
box.add_attribute (renderer, "visible", 2);
然后,控制行为的信号必须迭代商店/模型并设置可见性:
list_store.foreach ((model, path, iter) => {
list_store.set (iter, 2, true); // true to show, false to hide
return false;
});
如前所述,信号不合适,但这是一个简单的示例,仅适用于键盘(按Enter或空格键)以 pop 组合框,选择其他 Activity 行将恢复可见性。不完全是您想要的,但是显示了列表存储中需要完成的工作:
public class Application : Gtk.Window {
public Application () {
// Prepare Gtk.Window:
this.title = "My Gtk.ComboBox";
this.window_position = Gtk.WindowPosition.CENTER;
this.destroy.connect (Gtk.main_quit);
// Create & fill a ListStore:
Gtk.ListStore list_store = new Gtk.ListStore (3, typeof (string), typeof (int), typeof (bool));
Gtk.TreeIter iter;
list_store.append (out iter);
list_store.set (iter, 0, "Burgenland", 1, 13, 2, false);
list_store.append (out iter);
list_store.set (iter, 0, "Carinthia", 1, 17, 2, false);
// The Box:
Gtk.ComboBox box = new Gtk.ComboBox.with_model (list_store);
this.add (box);
Gtk.CellRendererText renderer = new Gtk.CellRendererText ();
box.pack_start (renderer, true);
box.add_attribute (renderer, "text", 0);
box.active = 0;
renderer = new Gtk.CellRendererText ();
box.pack_start (renderer, true);
box.add_attribute (renderer, "text", 1);
box.add_attribute (renderer, "visible", 2);
box.active = 0;
box.changed.connect (() => {
Value val1;
Value val2;
box.get_active_iter (out iter);
list_store.get_value (iter, 0, out val1);
list_store.get_value (iter, 1, out val2);
print ("Selection: %s, %d\n", (string) val1, (int) val2);
liststore_set_visibility (list_store, false);
});
box.popup.connect (() => {
print ("PopUp signal...\n");
liststore_set_visibility (list_store, true);
});
box.popdown.connect (() => {
print ("PopDown signal...\n");
return true;
});
}
private static void liststore_set_visibility (Gtk.ListStore list_store, bool visible) {
list_store.foreach ((model, path, iter) => {
list_store.set (iter, 2, visible);
return false;
});
}
public static int main (string[] args) {
Gtk.init (ref args);
Application app = new Application ();
app.show_all ();
Gtk.main ();
return 0;
}
}