Почему GTK 4 сообщает, что утверждение «GTK_IS_WIDGET (widget)« не выполнено »?
Я создал то, что я считаю самым простым приложением GTK 4 для создания окна с полосой меню, которая активируется при нажатии на пункт меню.
#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'><Primary>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;
}
Выполнение этого кода дает мне «критическое» сообщение об ошибке, когда я нажимаю «Выйти» в строке меню или когда я нажимаю только «Файл», а затем выхожу из раскрывающегося меню, не активируя пункт меню. Ошибка может возникать несколько раз за один запуск программы. Хотя приложение не аварийно завершает работу, очевидно, что некоторые базовые предположения о том, как работает 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» не зарегистрировано), то сообщение об ошибке не появляется. Это говорит о том, что проблема заключается в
Какой аспект моего кода вызывает сбой утверждения?
1 ответ
Я убежден, что это тривиальная ошибка в 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));
}