2012-09-19 122 views
0

我想在gtk + cairo繪圖區域繪製一些線條(實際上是一個正弦波),但我無法想出一個辦法來做到這一點。 因此,我的代碼首先定義了繪圖區域,該區域具有回調到繪圖區域本身的白色背景的函數...此時,我想在每次START按鈕之後開始繪製一段正弦波被按下(該按鈕有一個回調繪圖功能).... 所以首先..有可能做到這一點??我錯過了什麼? 謝謝。GTK +如何繪製繪圖區域

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

    int x = 0; 
    int x_old = 0; 
    float value = 0; 
    float value_old = 0; 
    GtkWidget *button = NULL; 
    GtkWidget *window = NULL; 
    GtkWidget *area = NULL; 
    GtkWidget *table = NULL; 

    static gboolean load_interface(GtkWidget *widget) 
    { 
    cairo_t *cr; 
    cr = gdk_cairo_create(area->window); 
    cairo_set_source_rgb(cr, 1, 1, 1); 
    cairo_rectangle(cr, 0, 0, 900, 400); 
    cairo_fill(cr); 
    } 

    void draw(GtkWidget *widget) 
    { 
    cairo_t *cr; 
    cr = gdk_cairo_create(widget->window); 

    x_old = x; 
    x = x + 15; 
    value_old = value; 
    value = value + 0.25; 

    cairo_set_source_rgb(cr, 0, 0, 0); 
    cairo_set_line_width (cr, 1); 
    cairo_move_to(cr, x_old, 100 + (sin(value_old))*50); 
    cairo_line_to(cr, x, 100 + (sin(value))*50); 
    cairo_stroke(cr); 
    } 


    int main (int argc, char *argv[]) 
    { 
     g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL); 
     gtk_init (&argc, &argv); 
     g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL); 

     window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
     gtk_container_set_border_width (GTK_CONTAINER (window), 3); 
     gtk_window_set_title (GTK_WINDOW (window), "Draw"); 
     gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); 
     gtk_widget_realize (window); 
     g_signal_connect (window, "destroy", gtk_main_quit, NULL); 

     table = gtk_table_new (10, 10, TRUE); 
     gtk_table_set_col_spacings(GTK_TABLE(table),10); 
     gtk_table_set_row_spacings(GTK_TABLE(table),5); 
     gtk_container_add (GTK_CONTAINER (window), table); 

     area = gtk_drawing_area_new(); 
     gtk_signal_connect (GTK_OBJECT(area), "event", G_CALLBACK (load_interface),  (gpointer)area); 
     gtk_table_attach_defaults (GTK_TABLE(table), area, 1, 10, 0, 10); 

     button = gtk_button_new_from_stock ("START"); 
     g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (draw), (gpointer) window); 
     gtk_table_attach_defaults (GTK_TABLE(table), button, 0, 1, 0, 1); 

     gtk_widget_show_all (window); 
     gtk_main(); 

     return 0; 
    } 
+1

您使用的是GTK2還是GTK3?看起來它是GTK2,但我不確定。 – liberforce

+0

是的,我在Windows上使用GTK2 ... – STiLLeN

回答

5

所有的繪圖都應該發生在繪圖區繪圖事件中,GTK2中稱爲expose-event,GTK3中稱爲draw。爲了響應點擊按鈕,您只需更改一些值,您將重新使用它們來計算繪製的整個場景。一旦您更改了這些值,您只需使繪圖區域無效以強制重繪,在繪圖區域調用gtk_widget_queue_draw。就是這樣。

如果場景繪製費用昂貴,請記住使用cairo剪裁函數通過僅繪製已更改的內容來提高性能。然後使用gtk_widget_queue_draw_area而不是gtk_widget_queue_draw,以提供有關已更改且需要重繪的區域的提示。

參見GtkDrawingArea documentation

順便說一句,不要使用強制轉換爲GTK_OBJECT(不建議使用),請改用G_OBJECT。這使得移植到GTK3更容易。