Gtk问题(关闭回调,不应该;开罗没有绘图;分隔符不出现)

时间:2015-01-02 19:52:52

标签: c terminal gtk cairo gtk2

我遇到了一些问题,我不知道如何用GTK + 2来解决。

  1. 我创建了一个函数,当我点击“Ajuda”(帮助)菜单上的“Manual”项时,它应该是一个回调函数。但是,当我编译并单击那里时,程序关闭,我不明白为什么。

  2. 开罗没有在其中一个方框上画画,事实上,它并没有在任何地方画画。

  3. 我尝试在菜单和工具栏之间创建一个水平分隔符,这似乎不可见。

  4. 对于半葡萄牙语的代码感到抱歉,我希望它不会有所作为......

       #include <gtk/gtk.h>
        #include <stdlib.h>
        #include <math.h>
        #include <cairo.h>
    
            /*FALTA:
              - Abrir o manual (dar mensagem de erro em caso de falha E compatibilidade com Windows/Mac)
    
            */            
    
            gboolean
            help_manual(void)
            {
              short int x;
              //x = system("xdg-open GCDmanual.pdf");
              /*if (x==-1)
                {
              */
              return TRUE;
            }
    
            gboolean
            on_expose_event (GtkWidget       *widget ,
                             GdkEventExpose  *event  ,
                             gpointer         data   )
            {
              cairo_t        *cr ;
              gchar           texto[128] ;
              gint            width, height;
    
              static double   pos1x = 100., pos1y = 80., pos2x = 600., pos2y = 100.;
              static double   s1x = 1., s1y = 0., s2x = 0., s2y = 0.; 
              static double   velscale1=4, velscale2=0;
              double r1=30, r2=50;
    
              gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
              cr = gdk_cairo_create(widget->window);
    
              cairo_move_to (cr, 20, 20);
              cairo_select_font_face(cr, "Courier", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
              cairo_set_font_size (cr, 18);
              sprintf (texto, "Exemplo de funcionamento de GTK+ Cairo                 Velocidade: %d\n",
                       (gint) velscale1);
              cairo_show_text (cr, texto);
    
              /* Circulo1 */
    
              cairo_set_source_rgb (cr, 0., 0., 0.);
              cairo_set_line_width (cr, 4.0);
              cairo_arc (cr, pos1x, pos1y, r1, 0., 2. * M_PI);
              cairo_stroke_preserve (cr);
              cairo_set_source_rgb (cr, 1, 1, 1);
              cairo_fill (cr);
    
              if ((pos1x < 30.) || ((pos1x + 30.) > width))
                s1x = - s1x;
    
    
              if ((pos1y < 30.) || ((pos1y + 30.) > height))
                s1y = - s1y;
              /* Circulo2 */
    
              cairo_set_source_rgb (cr, 0., 0., 0.);
              cairo_set_line_width (cr, 4.0);
              cairo_arc (cr, pos2x, pos2y, r2, 0., 2. * M_PI);
              cairo_stroke_preserve (cr);
              cairo_set_source_rgb (cr, 0, 1, 0);
              cairo_fill (cr);
    
              if ((pos2x < r2) || ((pos2x + r2) > width))
                s2x = - s2x;
    
    
              if ((pos2y < r2) || ((pos2y + r2) > height))
                s2y = - s2y;
    
              if ((pos1y-pos2y)*(pos1y-pos2y)+(pos1x-pos2x)*(pos1x-pos2x) <= (r1+r2)*(r1+r2))
                {
                  printf("COLISAO");
                  //angulovelrel
                  printf("%lf", atan2((s2y*velscale2-s1y*velscale1),(s2x*velscale2-s1x*velscale1)));
                  printf("%lf", atan2((pos2y-pos1y),(pos2x-pos1x)));
                }
              else
                {   
                  pos1x = pos1x + s1x * velscale1;
                  pos1y = pos1y + s1y * velscale1;
    
    
    
                  pos2x = pos2x + s2x * velscale2;
                  pos2y = pos2y + s2y * velscale2;
                }
    
    
              cairo_stroke(cr);
              cairo_destroy(cr);
    
              return FALSE;
            }
    
            static gboolean
            time_handler (GtkWidget *widget)
            {
              if (widget->window == NULL) 
                return FALSE;
    
              gtk_widget_queue_draw(widget);
    
              return TRUE;
            }
    
            int
            main(int argc, char **argv)
            {
    
              GtkWidget *janela;
              GtkWidget *vbox1, *hbox2, *vbox3_sett, *vbox3_field;
              GtkWidget *vboxseparator1;
              GtkWidget *menubar, *lvl1file, *lvl2file, *lvl1help, *lvl2help;
              GtkWidget *file_new, * file_open, *file_sep1, *file_quit;
              GtkWidget *help_manual, *help_about;
              GtkWidget *toolbar;
              GtkToolItem *tb_restart, *tb_pause, *tb_undo, *tb_redo, *tb_sep1;
              GtkWidget *statusbar;
    
    
    
              gtk_init(&argc, &argv);
    
              janela=gtk_window_new(GTK_WINDOW_TOPLEVEL);
              gtk_window_set_title(GTK_WINDOW(janela), "Grande Colisor de Discos");
              gtk_window_set_position (GTK_WINDOW (janela), GTK_WIN_POS_CENTER);
              gtk_window_set_default_size (GTK_WINDOW(janela), 800, 600); 
    
              g_signal_connect_swapped (G_OBJECT(janela), "destroy",
                                        G_CALLBACK(gtk_main_quit), NULL);
              g_signal_connect (janela, "expose-event", G_CALLBACK(on_expose_event), NULL);
    
    
              vbox1 = gtk_vbox_new (FALSE, 0);
              gtk_box_set_homogeneous (GTK_BOX (vbox1), FALSE);
              gtk_container_add (GTK_CONTAINER(janela), vbox1);
    
    
              /* MENU */
    
              menubar = gtk_menu_bar_new ();
              gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
    
              lvl1file= gtk_menu_item_new_with_mnemonic ("_Ficheiro"); 
              gtk_menu_shell_append (GTK_MENU_SHELL(menubar), lvl1file); 
              lvl2file = gtk_menu_new ();
              gtk_menu_item_set_submenu (GTK_MENU_ITEM (lvl1file), lvl2file);
    
              file_new = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, NULL);
            #if GTK_CHECK_VERSION(2,18,0)
              gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (file_new), TRUE);
            #endif
    
              file_open = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, NULL);
            #if GTK_CHECK_VERSION(2,18,0)
              gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (file_open), TRUE);
            #endif
    
              file_sep1= gtk_separator_menu_item_new();
              file_quit= gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
            #if GTK_CHECK_VERSION(2,18,0)
              gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (file_quit), TRUE);
            #endif
    
              gtk_menu_shell_append (GTK_MENU_SHELL (lvl2file), file_new);
              gtk_menu_shell_append (GTK_MENU_SHELL (lvl2file), file_open);
              gtk_menu_shell_append (GTK_MENU_SHELL (lvl2file), file_sep1);
              gtk_menu_shell_append (GTK_MENU_SHELL (lvl2file), file_quit);
    
    
    
              //Ajuda
    
              lvl1help = gtk_menu_item_new_with_mnemonic ("_Ajuda");
              gtk_menu_shell_append (GTK_MENU_SHELL (menubar), lvl1help);
              lvl2help = gtk_menu_new();
              gtk_menu_item_set_submenu (GTK_MENU_ITEM (lvl1help), lvl2help);
              help_manual=gtk_menu_item_new_with_label("Manual de ajuda");
              help_about= gtk_menu_item_new_with_label("Sobre...");
    
              gtk_menu_shell_append(GTK_MENU_SHELL(lvl2help), help_manual);
              gtk_menu_shell_append(GTK_MENU_SHELL(lvl2help), help_about);
    
    
    
              //Menu Callbacks
    
              g_signal_connect(G_OBJECT(file_quit), "activate", G_CALLBACK(gtk_main_quit), NULL);
              g_signal_connect(G_OBJECT(help_manual), "activate", G_CALLBACK(help_manual), NULL);
    
    
    
              /* TOOLBAR */
    
              toolbar = gtk_toolbar_new();
              gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
              gtk_container_set_border_width (GTK_CONTAINER (toolbar), 0);
    
              tb_undo = gtk_tool_button_new_from_stock (GTK_STOCK_UNDO);
              gtk_widget_set_name (GTK_WIDGET (tb_undo), "undo");
              gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tb_undo, -1);
    
              tb_redo = gtk_tool_button_new_from_stock (GTK_STOCK_REDO);
              gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tb_redo, -1);
    
              tb_sep1 = gtk_separator_tool_item_new ();
              gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tb_sep1, -1);
    
              tb_pause = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_PAUSE);
              gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tb_pause, -1);
    
              tb_restart = gtk_tool_button_new_from_stock (GTK_STOCK_REFRESH);
              gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tb_restart, -1);
    
              /*tb_sep = gtk_separator_tool_item_new ();
                gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tb_sep, -1);*/
    
              gtk_box_pack_start (GTK_BOX(vbox1), toolbar, FALSE, FALSE, 0); 
    
              /* HBOX2 */
    
              vboxseparator1 = gtk_hseparator_new ();
              gtk_box_pack_start (GTK_BOX (vbox1), vboxseparator1, FALSE, TRUE, 0);
              gtk_widget_show (vboxseparator1);
    
              hbox2= gtk_hbox_new (FALSE, 0);
              gtk_container_add (GTK_CONTAINER(vbox1), hbox2); 
    
              /* STATUSBAR */
    
              statusbar = gtk_statusbar_new();
              gtk_box_pack_end (GTK_BOX (vbox1), statusbar, FALSE, TRUE, 0);
              gtk_statusbar_push  (GTK_STATUSBAR (statusbar), 1, "  Isto e' uma     statusbar.");
    
              gtk_widget_show_all (janela);
              gtk_main();
    
    
              /* ÁREA DE TRABALHO */
    
              vbox3_field = gtk_vbox_new (FALSE, 0);
              gtk_container_add (GTK_CONTAINER (hbox2), vbox3_field);
    
              vbox3_sett = gtk_vbox_new (FALSE, 0);
              gtk_container_add (GTK_CONTAINER (hbox2), vbox3_sett);
    
              gtk_widget_set_app_paintable (vbox3_field, TRUE);
    }
    

1 个答案:

答案 0 :(得分:0)

GtkMenuItem * witdget的名称是help_manual它与函数名称冲突,并且在main()函数的范围内,您传递指针GtkMenuItem而不是回调,因为你的help_manualGtkMenuItem类型的指针而不是函数,修复是重命名回调

static void
help_manual_callback(GtkMenuItem *item, gpointer data)
{
  fprintf(stderr, "ajuda!\n");

  if (fork() == 0)
  {
    system("xdg-open GCDmanual.pdf");
    _exit(0);
  }
}

并连接

  g_signal_connect(G_OBJECT(help_manual), "activate", 
                       G_CALLBACK(help_manual_callback), NULL);

并且总是这样做,添加后缀或前缀来标识变量类型,这样可以更容易地跟踪类型。

这将解决崩溃,绘图问题取决于几何和其他东西,所以你应该检查它,看它是否正在绘制到正确的位置。

分隔符的可见性可能是一个主题问题,可能是您当前主题不可见的那些。

此外,您应该fork()在新流程中显示手册并保持流程运行,您可以使用线程,但我不认为它们在这种简单的情况下有用。 fork() + system()就可以了。虽然您可能希望通过指定help pdf文件的完整路径来使其更加健壮。

额外:你必须让你的代码遵循它自己的逻辑,我会为每个GUI部分创建函数,例如createToolbar()createMenu()等。它使阅读更容易。