2016-06-20 4 views
0

Здесь, в этом коде, я создал панель меню, а также добавил меню и пункты меню ... Но я не знаю, как сделать созданные пункты меню работоспособными .. . в течение, например: Я хочу, чтобы «открыть» пункт меню «файл» в строке меню, открыть файл и отобразить его ... Я делаю проект на текстовом редакторе с использованием GTK + 3Сделать пункты меню меню, созданные с помощью GTK +

#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

Для начала: вы не передаете окно в АКТИВИРУЙТЕ обратный вызов: 'g_signal_connect (G_OBJECT (openMi),«активировать», G_CALLBACK (fileOpen), NULL); 'должно быть' g_signal_connect (G_OBJECT (openMi), "активировать", G_CALLBACK (fileOpen), (gpointer) окно); '<-' gpointer' ('void *') - это то, как вы можете передать дополнительные данные для обратного вызова –

+0

Можете ли вы изменить коды и опубликовать их здесь? ... Я новичок в этом, так что это сложно для меня –

+0

Вы уже подключаетесь к сигналу 'activate', поэтому, где проблема? – oldtechaa

ответ

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, просто добавив ссылку на ответ для дальнейшего использования

Смежные вопросы