GTK Entry Completion 不仅仅通过前缀

GTK Entry Completion not only by prefix

我一直在使用 Gtk Entry Completion 小部件来显示建议,不仅基于您键入的前缀,还基于与搜索词匹配的所有子字符串,但该小部件表现不佳,因为它需要前缀匹配 (像 select 带箭头键,显示内联完成等。) 有没有一种简单的方法来支持它,或者我需要创建其他支持子字符串搜索的小部件?

我想你要找的是gtk_entry_completion_set_match_func()

void
gtk_entry_completion_set_match_func (GtkEntryCompletion *completion,
                                     GtkEntryCompletionMatchFunc func,
                                     gpointer func_data,
                                     GDestroyNotify func_notify);

Sets the match function for completion to be func . The match function is used to determine if a row should or should not be in the completion list.

Parameters

  • completion: a GtkEntryCompletion
  • func: the GtkEntryCompletionMatchFunc to use
  • func_data: user data for func
  • func_notify: destroy notify for func_data.

这里,func是一个布尔函数,如果要显示一行,应该return TRUE,否则FALSE

gboolean
(*GtkEntryCompletionMatchFunc) (GtkEntryCompletion *completion,
                                const gchar *key,
                                GtkTreeIter *iter,
                                gpointer user_data);

A function which decides whether the row indicated by iter matches a given key, and should be displayed as a possible completion for key. Note that key is normalized and case-folded (see g_utf8_normalize() and g_utf8_casefold()). If this is not appropriate, match functions have access to the unmodified key via gtk_entry_get_text (GTK_ENTRY (gtk_entry_completion_get_entry())).

Parameters

  • completion: the GtkEntryCompletion
  • key: the string to match, normalized and case-folded
  • iter: a GtkTreeIter indicating the row to match
  • user_data: user data given to gtk_entry_completion_set_match_func() Returns

TRUE if iter should be displayed as a possible completion for key


我已经使用以下简短(而且写得非常糟糕)的代码对此进行了测试:

#include <gtk/gtk.h>
#include <stdlib.h>

gboolean func(GtkEntryCompletion *completion,
              const gchar *key,
              GtkTreeIter *iter,
              gpointer user_data) {
    GtkTreeModel *model = gtk_entry_completion_get_model(completion);
    gchar *item;
    gtk_tree_model_get(model, iter, 0, &item, -1);
    gboolean ans = (atoi(key) % 2 == atoi(item) % 2);
    g_free(item);
    return ans;
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *entry = gtk_entry_new();
    GtkEntryCompletion *completion = gtk_entry_completion_new();
    GtkListStore *ls = gtk_list_store_new(1, G_TYPE_STRING);
    GtkTreeIter iter;
    int i;
    char buf[20];
    for(i=0; i<20; i++) {
        gtk_list_store_append(ls, &iter);
        sprintf(buf, "%d", i);
        gtk_list_store_set(ls, &iter, 0, buf, -1);
    }
    gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(ls));
    gtk_entry_completion_set_match_func(completion, (GtkEntryCompletionMatchFunc)func, NULL, NULL);
    gtk_entry_set_completion(GTK_ENTRY(entry), completion);
    gtk_entry_completion_set_text_column(completion, 0);
    gtk_container_add(GTK_CONTAINER(window), entry);
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}