c - 为什么 GTK 4 报告 "assertion ' GTK_IS_WIDGET(部件 )'

我已经创建了我认为最简单的 GTK 4 应用程序来创建一个带有菜单栏的窗口,该菜单栏在单击菜单项时激活 GAction

#include <stdio.h>
#include <assert.h>
#include <gtk/gtk.h>

static void
activate_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
    printf("Quit activated\n");
}

static void
startup(GApplication *app, gpointer user_data)
{
    assert(user_data == NULL);
    char *menubar_ui = (
        "<interface>"
        "   <menu id='menubar'>"
        "       <submenu>"
        "           <attribute name='label' translatable='yes'>_File</attribute>"
        "           <section>"
        "               <item>"
        "                   <attribute name='label' translatable='yes'>_Quit</attribute>"
        "                   <attribute name='action'>app.quit</attribute>"
        "                   <attribute name='accel'>&lt;Primary&gt;q</attribute>"
        "               </item>"
        "           </section>"
        "       </submenu>"
        "   </menu>"
        "</interface>"
    );
    GtkBuilder *builder = gtk_builder_new_from_string(menubar_ui, -1);
    GObject *menubar = gtk_builder_get_object(builder, "menubar");
    gtk_application_set_menubar(GTK_APPLICATION(app), G_MENU_MODEL(menubar));
    g_object_unref(builder);

    static GActionEntry app_entries[] = {
        { "quit", activate_quit, NULL, NULL, NULL, { 0 } },
    };
    g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries, G_N_ELEMENTS(app_entries), app);
}

static void
activate(GApplication *app, gpointer user_data)
{
    assert(user_data == NULL);
    GtkWidget *window = gtk_application_window_new(GTK_APPLICATION(app));
    assert(app != NULL);
    gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(window), TRUE);
    gtk_window_present(GTK_WINDOW(window));
}

int
main(int argc, char **argv)
{
    GtkApplication *app = gtk_application_new(NULL, G_APPLICATION_HANDLES_OPEN);
    g_signal_connect(app, "startup", G_CALLBACK(startup), NULL);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    int status = g_application_run(G_APPLICATION(app), 0, NULL);
    g_object_unref(app);
    return status;
}

当我单击菜单栏中的“退出”时,或者当我仅单击"file"然后退出下拉菜单而不激活菜单项时,运行此代码会给我一个“严重”错误消息。该错误可能会在程序的单次运行期间多次产生。虽然应用程序没有崩溃,但显然我对 GTK 4 的工作原理所做的一些基本假设是不正确的。

$ cc main.c `pkg-config --libs --cflags gtk4`
$ ./a.out
Quit activated

(a.out:13357): Gtk-CRITICAL **: 20:29:44.927: gtk_widget_child_focus: assertion 'GTK_IS_WIDGET (widget)' failed

我注意到如果“退出”菜单项未激活(因为“app.quit”操作未注册),则不会出现错误消息。这表明问题出在 GAction 系统,而不是 GtkBuilderGMenu 对象。

我的代码的哪个方面导致断言失败?

最佳答案

我确信这是 GTK 4 中的一个小错误。它只会影响不包含子项的窗口,因此在任何实际应用程序中都不会出现此错误。向窗口添加标签可以解决问题。

static void
activate(GApplication *app, gpointer user_data)
{
    assert(user_data == NULL);
    GtkWidget *window = gtk_application_window_new(GTK_APPLICATION(app));
    assert(app != NULL);
    gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(window), TRUE);
    GtkWidget *label = gtk_label_new("Hello world");
    gtk_window_set_child(GTK_WINDOW(window), label);
    gtk_window_present(GTK_WINDOW(window));
}

关于c - 为什么 GTK 4 报告 "assertion ' GTK_IS_WIDGET(部件 )' failed"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68340892/

相关文章:

node.js - 修复创建新 Angular 项目时的上游依赖冲突

schema - Protocol Buffer 架构无效。导入 "google/protobuf/

scala - Spark : Why execution is carried by a mast

email - 我应该用什么方法发送带有 Airflow 的电子邮件?

javascript - A 帧动画框在特定区域随机移动

java - 使用 Keycloak Script Mapper 聚合声明中角色的属性

javascript - 如何减少 GridStack 网格元素的最小高度和重量?

python - STATICFILES_DIRS 设置不是元组或列表。尽管它不包含逗号

chainlink - 布朗尼安装疑难解答

azure-devops - Azure Devops 管道 NPM 审计