如何制作 GtkComboBox 的项目 disabled/unclickable

How to make an item of a GtkComboBox disabled/unclickable

我一直在尝试禁用组合框的某些项目。我能得到的最好的办法是将文本颜色设为灰色并通过向组合添加属性来添加删除线,但我仍然可以 select "disabled" 项目并且悬停突出显示仍然是蓝色的,就像另一个一样, 活动项目。

理想的行为类似于分隔符,但不是大行,而是呈现项目的文本。

有什么想法吗?

一个解决方案可能是使用 GtkCellRenderer 并相应地将 "sensitive" 属性 设置为 gtk_cell_layout_set_cell_data_func,

Sets the GtkCellLayoutDataFunc to use for cell_layout . This function is used instead of the standard attributes mapping for setting the column value, and should set the value of cell_layout ’s cell renderer(s) as appropriate.

https://developer.gnome.org/gtk3/stable/GtkCellLayout.html#gtk-cell-layout-set-cell-data-func

例子

#include <glib/gi18n.h>
#include <gtk/gtk.h>

static GtkTreeModel *combo_model(void) {
    const gchar *labels[] = {
            N_("Show Bookmarks"),
            N_("Edit Bookmarks"),
            N_("Previous Item"),
            N_("Next Item"),
    };

    GtkListStore *store = gtk_list_store_new(1, G_TYPE_STRING);
    GtkTreeIter iter;
    for (gint i = 0; i < G_N_ELEMENTS(labels); i++) {
        gtk_list_store_append(store, &iter);
        gtk_list_store_set(store, &iter, 0, labels[i], -1);
    }

    return GTK_TREE_MODEL(store);
}

static void set_sensitive(GtkCellLayout *cell_layout,
              GtkCellRenderer *cell,
              GtkTreeModel *tree_model,
              GtkTreeIter *iter,
              gpointer data) {
    gchar *text;
    gtk_tree_model_get (tree_model, iter, 0, &text, -1);
    gboolean sensitive = g_strcmp0(N_("Previous Item"), text) != 0;
    g_free (text);
    g_object_set(cell, "sensitive", sensitive, NULL);
}


int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Disabled Item Demo");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_widget_destroyed), &window);
    gtk_container_set_border_width(GTK_CONTAINER(window), 32);

    GtkTreeModel *model = combo_model();
    GtkWidget *combo = gtk_combo_box_new_with_model(model);
    g_object_unref(model);
    gtk_container_add(GTK_CONTAINER(window), combo);

    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", 0, NULL);
    gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo), renderer, set_sensitive, NULL, NULL);
    gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);

    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

演示

当你运行上面的示例代码时,它看起来类似于: