使用GTK +创建菜单菜单项,可以使用

时间:2016-06-20 10:56:00

标签: c menu gtk

在这段代码中,我创建了一个菜单栏,并为其添加了菜单和菜单项...... 但我不知道如何使创建的菜单项可用...例如:我想要菜单栏中的'文件''打开'菜单项,打开文件并显示它... 我正在使用GTK + 3

在文本编辑器上创建项目
    #include <gtk/gtk.h>


    GtkWidget     *window;
    GdkPixbuf     *icon;
    GtkWidget     *vbox;

    GtkWidget     *menubar;
    GtkWidget     *fileMenu;
    GtkWidget     *fileMi;
    GtkWidget     *editMenu;
    GtkWidget     *editMi;
    GtkWidget     *searchMenu;
    GtkWidget     *searchMi;
    GtkWidget     *newMi;
    GtkWidget     *openMi;
    GtkWidget     *saveMi;
    GtkWidget     *saveasMi;
    GtkWidget     *quitMi;
    GtkWidget     *undoMi;
    GtkWidget     *redoMi;
    GtkWidget     *cutMi;
    GtkWidget     *copyMi;
    GtkWidget     *pasteMi;
    GtkWidget     *fontMi;
    GtkWidget     *findMi;
    GtkWidget     *replaceMi;
    GtkWidget     *text_view;
    GtkTextBuffer *buffer;

    void txt(){

    text_view = gtk_text_view_new ();
    gtk_box_pack_start (GTK_BOX (vbox), text_view, TRUE, TRUE, 0);


    }

    GdkPixbuf *create_pixbuf (const gchar *filename)
    {
    GdkPixbuf *pixbuf;
    GError    *error = NULL;

    pixbuf = gdk_pixbuf_new_from_file (filename, &error);

    if (!pixbuf)
    {
    fprintf (stderr, "%s\n", error->message);
    g_error_free (error);
    }

    return pixbuf;
    }

    static void fileOpen(GtkWidget *load, gpointer window)
    {
    GtkWidget *choose;
    GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;

    choose     =    gtk_file_chooser_dialog_new("Choose a file to open",  GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
    if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
    {

    char *path     = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(choose));
    gtk_text_buffer_set_text(buffer, path, -1);
    }

    gtk_widget_destroy(choose);
    }

    static void fileSave(GtkWidget *save, gpointer window)
    {
    GtkWidget *saved;

    saved     =    gtk_file_chooser_dialog_new("Choose a file to open",  GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
    gtk_widget_show_all(saved);

    gint resp    =     gtk_dialog_run(GTK_DIALOG(saved));

    gtk_widget_destroy(saved);
    }


    int main (int argc, char *argv[])
    {


    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    icon = create_pixbuf ("Web.png");

    gtk_window_set_title (GTK_WINDOW (window), "Write Pad");
    gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
    gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
    gtk_window_set_icon (GTK_WINDOW (window), icon);

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

    menubar = gtk_menu_bar_new ();
    fileMenu = gtk_menu_new ();


    fileMi = gtk_menu_item_new_with_label ("File");
    newMi = gtk_menu_item_new_with_label ("New");
    openMi = gtk_menu_item_new_with_label ("Open");
    saveMi = gtk_menu_item_new_with_label ("Save");
    saveasMi = gtk_menu_item_new_with_label ("Save As");
    quitMi = gtk_menu_item_new_with_label ("Quit");

    menubar = gtk_menu_bar_new ();
    editMenu = gtk_menu_new ();

    editMi = gtk_menu_item_new_with_label ("Edit");
    undoMi = gtk_menu_item_new_with_label ("Undo");
    redoMi = gtk_menu_item_new_with_label ("Redo");
    cutMi = gtk_menu_item_new_with_label ("Cut");
    copyMi = gtk_menu_item_new_with_label ("Copy");
    pasteMi = gtk_menu_item_new_with_label ("Paste");
    fontMi = gtk_menu_item_new_with_label ("Font");

    menubar = gtk_menu_bar_new ();
    searchMenu = gtk_menu_new ();

    searchMi = gtk_menu_item_new_with_label ("Search");
    findMi = gtk_menu_item_new_with_label ("Find");
    replaceMi = gtk_menu_item_new_with_label ("Replace");

    gtk_menu_item_set_submenu (GTK_MENU_ITEM (fileMi), fileMenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), newMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), openMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveasMi);
    gtk_menu_shell_append (GTK_MENU_SHELL (fileMenu), quitMi);
    gtk_menu_shell_append (GTK_MENU_SHELL (menubar), fileMi);

    gtk_menu_item_set_submenu (GTK_MENU_ITEM (editMi), editMenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), undoMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), redoMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), cutMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), copyMi);
    gtk_menu_shell_append (GTK_MENU_SHELL (editMenu), pasteMi);
    gtk_menu_shell_append (GTK_MENU_SHELL (editMenu), fontMi);
    gtk_menu_shell_append (GTK_MENU_SHELL (menubar), editMi);

    gtk_menu_item_set_submenu (GTK_MENU_ITEM (searchMi), searchMenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(searchMenu), findMi);
    gtk_menu_shell_append(GTK_MENU_SHELL(searchMenu), replaceMi);

    gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
    txt();
    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));

    g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
    g_signal_connect (G_OBJECT (quitMi), "activate", G_CALLBACK (gtk_main_quit), NULL);
    g_signal_connect (G_OBJECT (newMi), "activate", G_CALLBACK (main), NULL);
    g_signal_connect(G_OBJECT (openMi), "activate", G_CALLBACK(fileOpen), NULL);
    g_signal_connect(G_OBJECT (saveMi), "activate", G_CALLBACK(fileSave), NULL);

    gtk_widget_show_all (window);

    gtk_main ();

    return 0;
    }

1 个答案:

答案 0 :(得分:1)

基本上,您遇到的问题是由于您的所有小部件都是全局变量,但您的fileOpen函数需要gpointer window参数:

//global
GtkWidget *window;

//gpointer window argument -> local variable, not global
static void fileOpen(GtkWidget *load, gpointer window)
{
    GtkWidget *choose;
    GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;

    choose = gtk_file_chooser_dialog_new(
        "Choose a file to open",
        GTK_WINDOW(window),//window is not global, but function argument here !
        GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL
    );
    if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
    {
        char *path = gtk_file_chooser_get_filename(
            GTK_FILE_CHOOSER(choose)
        );
        gtk_text_buffer_set_text(buffer, path, -1);
    }
    gtk_widget_destroy(choose);
}

快速解决方法是将参数重命名为gp_data之类的东西。更好的解决方法是使用全局变量,而是依靠gpointer传递您需要的对象:

g_signal_connect(
    G_OBJECT (openMi),
    "activate",
    G_CALLBACK(fileOpen),
    (gpointer)text_view // text_view and buffer needn't be global now
);

然后使用gpointer参数获取窗口以及您可能需要的任何其他内容。您还可以使用自定义struct或小部件数组来传递回调,以防您需要更多内容,但在这种情况下,只需传递text_view小部件并更改回调即可这样的事情:

static void fileOpen(GtkWidget *load, gpointer widget)
{
    //get the buffer
    GtkTextBuffer *buffer = gtk_text_view_get_buffer(
        GTK_TEXT_VIEW (widget)
    );
    //get window from text_View widget passed to callback
    //so window doesn't have to be global either...
    GtkWidget *window = gtk_widget_get_toplevel(
        widget
    ), *choose;
    GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;

    choose = gtk_file_chooser_dialog_new(
        "Choose a file to open",
        GTK_WINDOW(window),
        GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL
    );
    if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
    {
        char *path = gtk_file_chooser_get_filename(
            GTK_FILE_CHOOSER(choose)
        );
        gtk_text_buffer_set_text(buffer, path, -1);
    }
    gtk_widget_destroy(choose);
}

请注意,我还没有测试过这段代码,但这应该足以让您入门。你必须改变你的代码,但你应该能够通过将正确的小部件传递给回调来摆脱所有这些全局变量。

一如既往:Read the documentation,只需添加答案的链接以供将来参考