这是我的建议:
使用GtkListStore包含与当前前缀字符串匹配的GTK管理的字符串列表(实际上是标识符字符串的副本)。
(如记录所示
gtk_list_store_set(),一个
G_TYPE_STRING项目已被复制。我认为额外副本的开销在这里是可以接受的;无论如何,我认为它不会对现实世界的性能产生太大影响,因此,GTK
+将为我们管理引用计数。)
上面的代码是在GTK
+回调函数中实现的,该函数获得一个额外的指针作为有效负载(在创建或激活GUI时设置;建议您使用某种结构来保留生成匹配项所需的引用)。回调连接到组合框
popup信号,以便在扩展列表时调用它。
请注意,正如B8vrede在评论中指出的那样,
GtkComboBoxText不应通过其模型修改a
;这就是为什么一个人应该/必须使用一个
GtkComboBox代替物的原因。
实际例子
为简单起见,我们假设查找或生成匹配的所有已知标识符所需的所有数据都保存在一个结构中,例如
struct generator { };然后组合框填充器助手功能类似于
static void combo_box_populator(GtkComboBox *combobox, gpointer genptr){ struct generator *const generator = genptr; GtkListStore *combo_list = GTK_LIST_STORE(gtk_combo_box_get_model(combobox)); GtkWidget *entry = gtk_bin_get_child(GTK_BIn(combobox)); const char *prefix = gtk_entry_get_text(GTK_ENTRY(entry)); const size_t prefix_len = (prefix) ? strlen(prefix) : 0; GtkTreeIter iterator; gtk_list_store_clear(combo_list); gtk_tree_model_get_iter_first(GTK_TREE_MODEL(combo_list), &iterator); gtk_list_store_append(combo_list, &iterator); gtk_list_store_set(combo_list, &iterator, 0, match, -1); }构建或激活UI时,您需要确保
GtkComboBox拥有一个条目(以便用户可以向其中写入文本)和一个
GtkListStore模型:
struct generator *generator; GtkWidget *combobox; GtkListStore *combo_list; combo_list = gtk_list_store_new(1, G_TYPE_STRING); combobox = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(combo_list)); gtk_combo_box_set_id_column(GTK_COMBO_BOX(combobox), 0); gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(combobox), 0); gtk_combo_box_set_button_sensitivity(GTK_COMBO_BOX(combobox), GTK_SENSITIVITY_ON); g_signal_connect(combobox, "popup", G_CALLBACK(combo_box_populator), generator);
在我的系统上,默认的弹出加速器为
Alt+
Down,但是我想您已经将其更改为
Tab。
我这里有一个粗糙的工作示例(
.tar.xztarball,CC0):它从标准输入中读取行,并在组合框列表中(当弹出时)以相反的顺序列出与用户前缀匹配的行。如果该项为空,则组合框将包含所有输入行。我没有更改默认的加速器,因此
Tab,请尝试
Alt+Down。
我也有相同的示例,但这里使用了
GtkComboBoxText替代示例(也是CC0)。这不使用模型,而是使用和函数直接操作列表内容。(两个示例中只有几行不同。)不幸的是,文档并未明确说明此接口是引用还是复制字符串。尽管复制是唯一有意义的选项,并且可以从当前的Gtk
+来源进行验证,但是缺少明确的文档使我犹豫不决。
GtkListStore
gtk_combo_box_text_remove_all()
gtk_combo_box_text_append_text()
比较上面链接到的两个示例(
/usr/share/dict/words如果使用进行编译和运行,都可以抓取500个随机单词
make),但看不到任何速度差异。两者都使用相同的简单方法从链接列表中选择前缀匹配,这意味着这两种方法(
GtkComboBox+模型或
GtkComboBoxText)应大致相同。
在我自己的计算机上,两者都令人讨厌地变慢,弹出窗口中的匹配项超过1000个左右。只需进行一百场或更少的比赛,就可以立即感受到。对我来说,这表明从链接列表中选择前缀匹配项的缓慢/幼稚方式不是罪魁祸首(因为在两种情况下都会遍历整个列表),但是GTK+组合框并不是专门为大型列表而设计的。(速度下降肯定比线性下降严重得多。)



