LINUX.ORG.RU

Как сделать меню 3-его уровня используя библиотеку Gtk+

 , ,


0

1

Очень интересуюсь тем, как сделать меню 3-его уровня. Ниже приведу листинг, с помощью которого получилось сделать строку меню с пунктом меню, по нажатию которого появляется меню. И для этого меню, свои пункты меню.

#include <gtk/gtk.h>
 
gint32 delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit();
    return FALSE;
}
 
int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *menu_bar;
    GtkWidget *menu;
    GtkWidget *box;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "menu");
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), "NULL");
 
    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), box);
 
    menu = gtk_menu_new(); // меню
    menu_bar = gtk_menu_bar_new(); // строка меню
    // создаем новые пункты меню
    GtkWidget *file_item = gtk_menu_item_new_with_label("file");
    GtkWidget *open_item = gtk_menu_item_new_with_label("open");
    GtkWidget *save_item = gtk_menu_item_new_with_label("save");
    GtkWidget *quit_item = gtk_menu_item_new_with_label("quit");
    // привязываем пункты меню к меню
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), open_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), save_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item);
    // обработчики сигналов для пунктов меню
    g_signal_connect_swapped(G_OBJECT(open_item), "activate", G_CALLBACK(delete_event), "NULL");
    g_signal_connect_swapped(G_OBJECT(save_item), "activate", G_CALLBACK(delete_event), "NULL");
    g_signal_connect_swapped(G_OBJECT(quit_item), "activate", G_CALLBACK(delete_event), "NULL");
 
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item);
 
    gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 3);
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}



Последнее исправление: TRomario (всего исправлений: 3)
Ответ на: комментарий от Vitaly1988

Я пробовал, но после компиляции приложение не запускается. В диспетчере задач его не видно. Добавил одну строку «gtk_menu_item_set_submenu(GTK_MENU_ITEM(open_item), menu);» Вот полный код:

#include <gtk/gtk.h>

gint32 delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit();
    return FALSE;
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *menu_bar;
    GtkWidget *menu;
    GtkWidget *box;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "menu");
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), "NULL");

    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), box);

    menu = gtk_menu_new(); // меню
    menu_bar = gtk_menu_bar_new(); // строка меню
    // создаем новые пункты меню
    GtkWidget *file_item = gtk_menu_item_new_with_label("file");
    GtkWidget *open_item = gtk_menu_item_new_with_label("open");
    GtkWidget *save_item = gtk_menu_item_new_with_label("save");
    GtkWidget *quit_item = gtk_menu_item_new_with_label("quit");
    // привязываем пункты меню к меню
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), open_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), save_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item);
    // обработчики сигналов для пунктов меню
    //g_signal_connect_swapped(G_OBJECT(open_item), "activate", G_CALLBACK(delete_event), "NULL");
    //g_signal_connect_swapped(G_OBJECT(save_item), "activate", G_CALLBACK(delete_event), "NULL");
    g_signal_connect_swapped(G_OBJECT(quit_item), "activate", G_CALLBACK(delete_event), "NULL");

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), menu);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(open_item), menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item);

    gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 3);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}
Помогите направить меня в правильную сторону. Если не кодом, то идеей..Много времени потратил, а результата практически не видно

TRomario
() автор топика
Ответ на: комментарий от TRomario

Субменю надо создавать и заполнять таким же образом, как и корневое

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

gint32 delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit();
    return FALSE;
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *menu_bar;
    GtkWidget *menu;
    GtkWidget *box;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "menu");
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), "NULL");

    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), box);

    menu = gtk_menu_new(); // меню
    menu_bar = gtk_menu_bar_new(); // строка меню
    // создаем новые пункты меню
    GtkWidget *file_item = gtk_menu_item_new_with_label("file");
    GtkWidget *open_item = gtk_menu_item_new_with_label("open");
    GtkWidget *save_item = gtk_menu_item_new_with_label("save");
    GtkWidget *quit_item = gtk_menu_item_new_with_label("quit");
    // привязываем пункты меню к меню
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), open_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), save_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item);
    // обработчики сигналов для пунктов меню
    //g_signal_connect_swapped(G_OBJECT(open_item), "activate", G_CALLBACK(delete_event), "NULL");
    //g_signal_connect_swapped(G_OBJECT(save_item), "activate", G_CALLBACK(delete_event), "NULL");
    g_signal_connect_swapped(G_OBJECT(quit_item), "activate", G_CALLBACK(delete_event), "NULL");

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), menu);
 //////////////////////////////////////////////////////////   
    menu = gtk_menu_new(); // меню 2
    GtkWidget *open1 = gtk_menu_item_new_with_label("open1");
    GtkWidget *open2 = gtk_menu_item_new_with_label("open2");
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), open1);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), open2);
 ///////////////////////////////////////////////////////////   
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(open_item), menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item);

    gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 3);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}

Vitaly1988
()
Ответ на: комментарий от Vitaly1988

Большое спасибо! Работает.
Отличие версии в том, что Вы создали новое меню и пункты для него. Почему меню, которое я сделал первым(корневое), не получилось сделать внутренним для другого пункта? Чтобы уж точно разобраться.
Приведу код ещё раз:

#include <gtk/gtk.h>

gint32 delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    gtk_main_quit();
    return FALSE;
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *menu_bar;
    GtkWidget *menu;
    GtkWidget *box;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "menu");
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), "NULL");

    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), box);

    menu = gtk_menu_new(); // меню
    menu_bar = gtk_menu_bar_new(); // строка меню
    // создаем новые пункты меню
    GtkWidget *file_item = gtk_menu_item_new_with_label("file");
    GtkWidget *open_item = gtk_menu_item_new_with_label("open");
    GtkWidget *save_item = gtk_menu_item_new_with_label("save");
    GtkWidget *quit_item = gtk_menu_item_new_with_label("quit");
    // привязываем пункты меню к меню
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), open_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), save_item);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item);
    // обработчики сигналов для пунктов меню
    //g_signal_connect_swapped(G_OBJECT(open_item), "activate", G_CALLBACK(delete_event), "NULL");
    //g_signal_connect_swapped(G_OBJECT(save_item), "activate", G_CALLBACK(delete_event), "NULL");
    g_signal_connect_swapped(G_OBJECT(quit_item), "activate", G_CALLBACK(delete_event), "NULL");

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), menu);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(open_item), menu);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item);

    gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 3);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}

TRomario
() автор топика
Ответ на: комментарий от TRomario

потому что одно и то же меню может быть прикреплено только к одному виджету.

Vitaly1988
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.