问题描述
我已经创建了我认为最简单的 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'><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,{ 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),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”操作未注册),则不会出现错误消息。这表明问题在于 GAction
系统,而不是 GtkBuilder
或 GMenu
对象。
我的代码的哪个方面导致断言失败?
解决方法
我确信这是 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));
}