在一个小例子中,我不明白这是什么问题。
我想用Gmenu而不在GtkApplication中实现Gaction
首先请用GtkApplication找到一个小例子
我拿了here
#include <gtk/gtk.h>
//menubuttonexample.c
/* Compile with:
* gcc -std=c11 -Wall -fmax-errors=10 -Wextra menubuttonexample.c -o menubuttonexample `pkg-config --cflags --libs gtk+-3.0 `
*/
/* Callback function for the undo action */
static void about_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
g_print ("You clicked \"About\"\n");
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void new_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
g_print ("You clicked \"New\"\n");
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void quit_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
GApplication *application = user_data;
g_application_quit (application);
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void activate (GtkApplication *app, gpointer user_data)
{
GMenu *submenu;
GtkWidget *grid;
GMenu *menumodel;
GtkWidget *window;
GtkWidget *menubutton;
GSimpleAction *about_action;
window = gtk_application_window_new (app);
grid = gtk_grid_new ();
gtk_window_set_title (GTK_WINDOW (window), "MenuButton Example");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
menubutton = gtk_menu_button_new ();
gtk_widget_set_size_request (menubutton, 80, 35);
gtk_grid_attach (GTK_GRID (grid), menubutton, 0, 0, 1, 1);
gtk_container_add (GTK_CONTAINER (window), grid);
menumodel = g_menu_new ();
g_menu_append (menumodel, "New", "app.new");
g_menu_append (menumodel, "About", "win.about");
submenu = g_menu_new ();
g_menu_append_submenu (menumodel, "Other", G_MENU_MODEL (submenu));
g_menu_append (submenu, "Quit", "app.quit");
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menubutton), G_MENU_MODEL (menumodel));
about_action = g_simple_action_new ("about", NULL);
g_signal_connect (about_action, "activate", G_CALLBACK (about_callback),
GTK_WINDOW (window));
g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (about_action));
gtk_widget_show_all (window);
// not used
(void)user_data;
}
static void startup (GApplication *app, gpointer user_data)
{
GSimpleAction *new_action;
GSimpleAction *quit_action;
new_action = g_simple_action_new ("new", NULL);
g_signal_connect (new_action, "activate", G_CALLBACK (new_callback), app);
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (new_action));
quit_action = g_simple_action_new ("quit", NULL);
g_signal_connect (quit_action, "activate", G_CALLBACK (quit_callback), app);
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (quit_action));
// not used
(void)user_data;
}
int main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
第一个代码对我来说运行正常。
在第二步中,我尝试使用gtk_window和不使用GtkApplication进行相同的操作
请找到以下代码
#include <gtk/gtk.h>
#include <stdlib.h>
//menubuttonexample_ter.c
/* Compile with:
* gcc -std=c11 -Wall -fmax-errors=10 -Wextra menubuttonexample_ter.c -o menubuttonexample_ter `pkg-config --cflags --libs gtk+-3.0 `
*/
/** le même que menubuttonexample mais en version non Gtkapplication */
/* Callback function for the undo action */
static void about_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
g_print ("You clicked \"About\"\n");
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void new_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
g_print ("You clicked \"New\"\n");
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void quit_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
GApplication *application = user_data;
g_application_quit (application);
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static GActionGroup * create_action_group (void)
{
const GActionEntry entries[] = {
{ "win.quit", quit_callback, NULL, NULL, NULL,{0,0,0} },
{ "win.new", new_callback, NULL, NULL, NULL,{0,0,0} },
{ "win.about", about_callback ,NULL, NULL, NULL,{0,0,0} }
};
GSimpleActionGroup *group;
group = g_simple_action_group_new ();
g_action_map_add_action_entries (G_ACTION_MAP (group), entries, G_N_ELEMENTS (entries), NULL);
return G_ACTION_GROUP (group);
}
static GtkWidget* create_main_window (void)
{
GMenu *submenu;
GtkWidget *grid;
GMenu *menumodel;
GtkWidget *window;
GtkWidget *menubutton;
//GSimpleAction *about_action;
//GSimpleAction *new_action;
//GSimpleAction *quit_action;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "MenuButton Example");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
#define G_MENU_ATTRIBUTE_ACTION "win"
GActionGroup * group = NULL;
group = create_action_group(); // I don't know to link Gmenu and group
/* Lorsque le shell affiche le menu de l'application, les actions de type "win"font référence à la copie
* de cette action sur la fenêtre actuellement active.
* Si une telle action n'existe pas, l'élément de menu sera grisé.
* ===> c'est exactement ce que je constate à date */
grid = gtk_grid_new ();
menubutton = gtk_menu_button_new ();
gtk_widget_set_size_request (menubutton, 80, 35);
/* essai */
gtk_widget_map(GTK_WIDGET(menubutton));
gtk_grid_attach (GTK_GRID (grid), menubutton, 0, 0, 1, 1);
gtk_container_add (GTK_CONTAINER (window), grid);
menumodel = g_menu_new ();
g_menu_append (menumodel, "New", "win.new");
g_menu_append (menumodel, "About", "win.about");
submenu = g_menu_new ();
g_menu_append_submenu (menumodel, "Other", G_MENU_MODEL (submenu));
// from the menu, we refer to the action as "app.quit" since we installed it on the application
g_menu_append (submenu, "Quit", "win.quit");
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menubutton), G_MENU_MODEL (menumodel));
return window;
}
int main (int argc, char **argv)
{
GtkWidget *window = NULL;
/* Initialisation de GTK+ */
gtk_init (&argc, &argv);
g_print("Version de gtk: %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version);
/* Creation du conteneur principal */
window = create_main_window();
/* Affichage de la fenetre principale */
gtk_widget_show_all (window);
/* Lancement de la boucle principale */
gtk_main ();
return EXIT_SUCCESS;
}
表示信息的级别。好像还可以因为与第一个示例相同。
问题纯粹是功能性的。
我不喜欢如何将GAction或GActiongroup实例组与Gmenu链接为menumodel。
请帮忙,因为我有一天没有解决方案就用Google搜索
最佳答案
我发现解决方案只需要两个命令
/* Implémentation of GActionMap interface */
GActionGroup *actions =(GActionGroup*)g_simple_action_group_new ();
/* namespace "win" created and linked with action*/
gtk_widget_insert_action_group (window, "win", actions);
#include <gtk/gtk.h>
#include <stdlib.h>
//menubuttonexample_ter.c
/* Compile with:
* gcc -std=c11 -Wall -fmax-errors=10 -Wextra menubuttonexample_ter.c -o menubuttonexample_ter `pkg-config --cflags --libs gtk+-3.0 `
*/
/** le même que menubuttonexample mais en version non Gtkapplication */
/* Callback function for the undo action */
static void about_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
g_print ("You clicked \"About\"\n");
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void new_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
g_print ("You clicked \"New\"\n");
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static void quit_callback (GSimpleAction *simple, GVariant *parameter, gpointer user_data)
{
gtk_main_quit();
// not used
(void)simple;
(void)parameter;
(void)user_data;
}
static GtkWidget* create_main_window (void)
{
GMenu *submenu;
GtkWidget *grid;
GMenu *menumodel;
GtkWidget *window;
GtkWidget *menubutton;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "MenuButton Example");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
grid = gtk_grid_new ();
menubutton = gtk_menu_button_new ();
gtk_widget_set_size_request (menubutton, 80, 35);
gtk_grid_attach (GTK_GRID (grid), menubutton, 0, 0, 1, 1);
gtk_container_add (GTK_CONTAINER (window), grid);
/* Implémentation de l'interface GActionMap, une interface exposant un mappage de noms d'action à des GActions*/
GActionGroup *actions =(GActionGroup*)g_simple_action_group_new ();
/* création de l'espace de nom "win" qui va lier les actions et le widget principal window */
gtk_widget_insert_action_group (window, "win", actions);
const GActionEntry entries[] = {
{ "quit", quit_callback, NULL, NULL, NULL,{0,0,0} },
{ "new", new_callback, NULL, NULL, NULL,{0,0,0} },
{ "about", about_callback ,NULL, NULL, NULL,{0,0,0} }
};
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), window);
/** partie couche de présentation **/
/* création du premier menu */
menumodel = g_menu_new ();
g_menu_append (menumodel, "New", "win.new");
g_menu_append (menumodel, "About","win.about");
/** le sous-menu **/
submenu = g_menu_new ();
g_menu_append_submenu (menumodel, "Other", G_MENU_MODEL (submenu));
g_menu_append (submenu, "Quit", "win.quit");
/** association du menu au GtkMenuButton **/
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menubutton), G_MENU_MODEL (menumodel));
return window;
}
int main (int argc, char **argv)
{
GtkWidget *window = NULL;
/* Initialisation de GTK+ */
gtk_init (&argc, &argv);
g_print("Version de gtk: %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version);
/* Creation du conteneur principal */
window = create_main_window();
/* Affichage de la fenetre principale */
gtk_widget_show_all (window);
/* Lancement de la boucle principale */
gtk_main ();
return EXIT_SUCCESS;
}