我正在测试GTK4列视图列表模型以显示多列. 用C编码 我有这个代码工作(见下面的代码).我使用GTK4.0文档中引用的C代码片段作为指南,在添加标准的列视图排序函数时遇到了麻烦

C代码片段如下所示:https://docs.gtk.org/gtk4/method.ColumnView.get_sorter.html

工作代码,预排序try ,如下. 应用程序显示列,没有错误的std出来,工作正常.

// Use for testing columnview

#include <gtk/gtk.h>

// Setup custom type - each item has two strings which will be displayed in two columns

#define TESTCOL_TYPE_ITEM (testcol_item_get_type())
G_DECLARE_FINAL_TYPE (TestColItem, testcol_item, TESTCOL, ITEM, GObject)

struct _TestColItem
{
    GObject parent_instance;
    const char *str1;
    const char *str2;
};

struct _TestColItemClass
{
    GObjectClass parent_class;
};

G_DEFINE_TYPE (TestColItem, testcol_item, G_TYPE_OBJECT)

static void testcol_item_init(TestColItem *item)
{
}

static void testcol_item_class_init(TestColItemClass *class)
{
}
enter image description here
// Set label for factory widget
static void setup_cb(GtkSignalListItemFactory *factory,GObject  *listitem)
{
    GtkWidget *label =gtk_label_new(NULL);
    gtk_list_item_set_child(GTK_LIST_ITEM(listitem),label);
}

// Set text from the column1 passed item for label
static void bind_col1_cb(GtkSignalListItemFactory *factory, GtkListItem *listitem)
{
    GtkWidget *label = gtk_list_item_get_child(listitem);
    TestColItem *item = gtk_list_item_get_item(GTK_LIST_ITEM(listitem));
    const char *string = item->str1;
    g_print("value is %s\n",string); // Show on std out
    gtk_label_set_text(GTK_LABEL (label), string);
}
// Set text from the column2 passed item for label
static void bind_col2_cb(GtkSignalListItemFactory *factory, GtkListItem *listitem)
{
    GtkWidget *label = gtk_list_item_get_child(listitem);
    TestColItem *item = gtk_list_item_get_item(GTK_LIST_ITEM(listitem));
    const char *string = item->str2;
    g_print("value is %s\n",string); // Show on std out
    gtk_label_set_text(GTK_LABEL (label), string);
}

// Create the custom object
static TestColItem * testcol_item_new(const char *str1, const char *str2)
{
    TestColItem  *item = g_object_new(TESTCOL_TYPE_ITEM, NULL);
    item->str1 = g_strdup(str1);
    item->str2 = g_strdup(str2);
    return item;
}   

// Activate
static void activate (GtkApplication* app, gpointer user_data)
{
    // Create and populate custom list model
    GListStore *store = g_list_store_new(G_TYPE_OBJECT); 
    GListModel *model = G_LIST_MODEL(store);

    g_list_store_append(store,testcol_item_new("abc1","ghi1"));
    g_list_store_append(store,testcol_item_new("def2","aaa2"));
    g_list_store_append(store,testcol_item_new("aaa3","jkl3"));

    // Set selection for custom model
    GtkSingleSelection *selection = gtk_single_selection_new(G_LIST_MODEL(model));
    gtk_single_selection_set_autoselect(selection,TRUE);

    // Set Windows in child scrolled window
    GtkWidget *window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Test");
    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
    GtkWidget *scrolled_window = gtk_scrolled_window_new (); 
    gtk_window_set_child (GTK_WINDOW(window), scrolled_window);

    // Add column view.  Put in scrolled window.  
    GtkWidget *cv = gtk_column_view_new(GTK_SELECTION_MODEL (selection));
    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolled_window),cv);
    gtk_column_view_set_show_column_separators (GTK_COLUMN_VIEW (cv),TRUE);

    // Factory setup and bind for column view
    GtkListItemFactory *factory = gtk_signal_list_item_factory_new();
    g_signal_connect(factory, "setup", G_CALLBACK(setup_cb),NULL);
    g_signal_connect(factory, "bind", G_CALLBACK(bind_col1_cb),NULL);
    GtkColumnViewColumn *column = gtk_column_view_column_new("Col1", factory);
    gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);

    // Factory setup and bind for column view
    factory = gtk_signal_list_item_factory_new();
    g_signal_connect(factory, "setup", G_CALLBACK(setup_cb),NULL);
    g_signal_connect(factory, "bind", G_CALLBACK(bind_col2_cb),NULL);
    column = gtk_column_view_column_new("Col2", factory);
    gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);


    // Show window
    gtk_window_present (GTK_WINDOW (window));
}

// Init application
int main (int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

问题

我try 使用上面的C代码片段作为指南添加排序功能. 当工作时,我们会在列标题中看到一个排序图标,当点击该图标时,会激活排序. 很多代码测试变体,这是一个:

首先,我注释掉了gtk_column_view_append_column,然后添加了:

    // First comment out append and then add
    GtkSorter *sorter = gtk_column_view_get_sorter ((GtkColumnView *) cv); // get the sorter for col
    gtk_column_view_column_set_sorter(column, sorter); // set the sorter on column
    gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column); // put col into colview
    GtkSortListModel *smodel = gtk_sort_list_model_new ((GListModel *) model, sorter);
    selection = gtk_single_selection_new(G_LIST_MODEL(smodel));
    gtk_column_view_set_model ((GtkColumnView *)cv, (GtkSelectionModel *)selection);

STD Out显示.

(out:22870):GLib—GIO—CRITICAL **:21:39:59.759:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.759:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.759:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.759:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.759:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.759:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.797:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

(out:22870):GLib—GIO—CRITICAL **:21:39:59.807:g_list_model_get_n_items:断言'G_IS_LIST_MODEL(list)'失败

显然我不明白. 继续进行实验,但如果能提供任何关于如何将C代码添加到我的工作示例中的建议,该示例在两个列上引入了排序功能.

推荐答案

如错误消息所示,str1和str2尚未实现为属性.我在列表中相应地添加了这一点.现在起作用了.


// Use for testing columnview

#include <gtk/gtk.h>

// Setup custom type - each item has two strings which will be displayed in two columns

#define TESTCOL_TYPE_ITEM (testcol_item_get_type())
G_DECLARE_FINAL_TYPE (TestColItem, testcol_item, TESTCOL, ITEM, GObject)

struct _TestColItem
{
    GObject parent_instance;
     char *str1;
     char *str2;
};

struct _TestColItemClass
{
    GObjectClass parent_class;
};

G_DEFINE_TYPE (TestColItem, testcol_item, G_TYPE_OBJECT)

enum {
    PROP_STR1 = 1,
    PROP_STR2 = 2,
    N_PROPERTIES
};

static void
testcol_item_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
    TestColItem *self = (TestColItem *)object;

    switch (prop_id) {
    case PROP_STR1:
        g_value_set_string(value, self->str1);
        break;
    case PROP_STR2:
       g_value_set_string(value, self->str2);
       break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}

static void
testcol_item_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
    TestColItem *self = (TestColItem *)object;

    switch (prop_id) {
    case PROP_STR1:
        g_free(self->str1);
        self->str1 = g_value_dup_string(value);
        break;
    case PROP_STR2:
        g_free(self->str2);
        self->str2 = g_value_dup_string(value);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}

static void testcol_item_init(TestColItem *item)
{
    item->str1 = NULL;
    item->str2 = NULL;
}


static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

static void testcol_item_class_init(TestColItemClass *class)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS(class);

    gobject_class->get_property = testcol_item_get_property;
    gobject_class->set_property = testcol_item_set_property;

    obj_properties[PROP_STR1] = g_param_spec_string("str1",
                                                    "Str1",
                                                    "first column",
                                                    NULL,
                                                    G_PARAM_READWRITE);

    obj_properties[PROP_STR2] = g_param_spec_string("str2",
                                                    "Str2",
                                                    "second column",
                                                    NULL,
                                                    G_PARAM_READWRITE);

    g_object_class_install_properties(gobject_class, N_PROPERTIES, obj_properties);
}


// Set label for factory widget
static void setup_cb(GtkSignalListItemFactory *factory,GObject  *listitem)
{
    GtkWidget *label =gtk_label_new(NULL);
    gtk_list_item_set_child(GTK_LIST_ITEM(listitem),label);
}

// Set text from the column1 passed item for label
static void bind_col1_cb(GtkSignalListItemFactory *factory, GtkListItem *listitem)
{
    GtkWidget *label = gtk_list_item_get_child(listitem);
    TestColItem *item = gtk_list_item_get_item(GTK_LIST_ITEM(listitem));
    const char *string = item->str1;
    g_print("value is %s\n",string); // Show on std out
    gtk_label_set_text(GTK_LABEL (label), string);
}
// Set text from the column2 passed item for label
static void bind_col2_cb(GtkSignalListItemFactory *factory, GtkListItem *listitem)
{
    GtkWidget *label = gtk_list_item_get_child(listitem);
    TestColItem *item = gtk_list_item_get_item(GTK_LIST_ITEM(listitem));
    const char *string = item->str2;
    g_print("value is %s\n",string); // Show on std out
    gtk_label_set_text(GTK_LABEL (label), string);
}

// Create the custom object
static TestColItem * testcol_item_new(const char *str1, const char *str2)
{
    TestColItem  *item = g_object_new(TESTCOL_TYPE_ITEM, NULL);
    item->str1 = g_strdup(str1);
    item->str2 = g_strdup(str2);
    return item;
}   

// Activate
static void activate (GtkApplication* app, gpointer user_data)
{
    // Create and populate custom list model
    GListStore *store = g_list_store_new(G_TYPE_OBJECT); 
    g_list_store_append(store,testcol_item_new("abc1","ghi1"));
    g_list_store_append(store,testcol_item_new("def2","aaa2"));
    g_list_store_append(store,testcol_item_new("aaa3","jkl3"));

    // Set Windows in child scrolled window
    GtkWidget *window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Test");
    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
    GtkWidget *scrolled_window = gtk_scrolled_window_new (); 
    gtk_window_set_child (GTK_WINDOW(window), scrolled_window);

    // Add column view.  Put in scrolled window.  
    GtkWidget *cv = gtk_column_view_new(NULL); // Null for now want to add sorter
    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolled_window),cv);
    gtk_column_view_set_show_column_separators (GTK_COLUMN_VIEW (cv),TRUE);
     
    // Setup sort model then overlay with with columnview
    GtkSorter *sorter = g_object_ref (gtk_column_view_get_sorter (GTK_COLUMN_VIEW (cv)));
    GtkSortListModel *model = gtk_sort_list_model_new (G_LIST_MODEL (store), sorter);
    GtkSingleSelection *selection = gtk_single_selection_new (G_LIST_MODEL (model));
    gtk_single_selection_set_autoselect (selection, TRUE);
    gtk_column_view_set_model (GTK_COLUMN_VIEW (cv), GTK_SELECTION_MODEL (selection));

    // Factory setup and bind for column 1 
    GtkListItemFactory *factory = gtk_signal_list_item_factory_new();
    g_signal_connect(factory, "setup", G_CALLBACK(setup_cb),NULL);
    g_signal_connect(factory, "bind", G_CALLBACK(bind_col1_cb),NULL);
    GtkColumnViewColumn *column = gtk_column_view_column_new("Col1", factory);
    sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (TESTCOL_TYPE_ITEM,NULL,"str1")));
    gtk_column_view_column_set_sorter (column, GTK_SORTER (sorter));
    gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);

    // Factory setup and bind for column 2
    factory = gtk_signal_list_item_factory_new();
    g_signal_connect(factory, "setup", G_CALLBACK(setup_cb),NULL);
    g_signal_connect(factory, "bind", G_CALLBACK(bind_col2_cb),NULL);
    column = gtk_column_view_column_new("Col2", factory);
    sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (TESTCOL_TYPE_ITEM, NULL, "str2")));
    gtk_column_view_column_set_sorter (column, GTK_SORTER (sorter));
    gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);

    // Show window
    gtk_window_present (GTK_WINDOW (window));
}

// Init application
int main (int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

enter image description here

C++相关问答推荐

exit(EXIT_FAILURE):Tcl C API类似功能

为什么复合文字(C99)的返回会生成更多的汇编代码?

为什么可以通过指向常量int的指针间接地改变整数的值?

如何使fputs功能提示错误输入并要求用户重新输入.程序停止而不是请求新的输入

如何跨平台处理UTF-16字符串?

调用mProtection将堆栈上的内存设置为只读,直接导致程序SIGSEGV

`#if`条件中是否允许`sizeof`?

理解C版宏(看起来像未声明的变量?)

为什么memcpy进入缓冲区和指向缓冲区的指针工作相同?

为什么此共享库没有预期的依赖项?

I2C外设在单次交易后出现故障

Cairo STM32MP1 cairo_Surface_WRITE_TO_PNG始终返回CAROLIO_STATUS_WRITE_ERROR

在进程之间重定向输出和输入流的问题

Fscanf打印除退出C代码为1的程序外的所有内容

问题:C#Define上的初始值设定项元素不是常量

如何在C中处理流水线中的a、n命令?

c如何传递对 struct 数组的引用,而不是设置 struct 的副本

模仿 memmove 的行为

使用替代日历打印日期

创建 makefile 来编译位于不同目录中的多个源文件