2017-06-21 62 views
0

如何使用cairo重繪文本我正在使用cairo來繪製一些圓形小部件,如this使用gtk +

我使用繪製區域的「繪製」事件來繪製所有的小部件,但我不知道如何更新小部件中的數據。 這是我做的代碼:

gboolean hald_circular_gauge (GtkWidget *widget,cairo_t *cr, gdouble max, gdouble min, gdouble value, gchar *pcname ,gchar *unit){ 

cairo_text_extents_t extents, extentsTemp, extentsLabel, extentsTempMin, extentsTempMax; 
    int width, height; 
    gint percentage, linewidth; 
    double x,y; 
    gdouble declive = (360.0-180.0)/(max-min); 
    gdouble origin = 180.0 - declive*min; 
    gchar pcTemp[BUFSIZ]; 

    width = gtk_widget_get_allocated_width (widget); 
    height = gtk_widget_get_allocated_height (widget); 



    double angle1 = 180.0 * (M_PI/180.0); /* angles are specified */ 
    double angle2 = 360.0 * (M_PI/180.0); /* in radians   */ 

    if(min > value || value >max) 
     return FALSE; 

    linewidth = (MIN (width, height)/2.0 * 30.0)/100.0; 

    cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6); 
    cairo_set_line_width (cr, linewidth); 
    cairo_arc(cr, width/2.0, height/2.0, MIN (width, height)/2.0 - linewidth, angle1, angle2); 
    cairo_stroke (cr); 

    cairo_set_source_rgba (cr, 0.0, 0.9, 0.0, 1.0); 
    cairo_set_line_width (cr, linewidth); 
    cairo_arc(cr, width/2.0, height/2.0, MIN (width, height)/2.0 - linewidth, 180.0 * (M_PI/180.0),(declive*value+origin) * (M_PI/180.0)); 
    cairo_stroke (cr); 

    cairo_select_font_face (cr, "Roboto Thin", CAIRO_FONT_SLANT_NORMAL, 
      CAIRO_FONT_WEIGHT_NORMAL); 
    cairo_set_font_size (cr, linewidth); 
    cairo_set_source_rgb (cr, 1.0, 1.0, 1); 
    cairo_text_extents (cr, unit, &extents); 
    x = width/2.0-(extents.width/2 + extents.x_bearing); 
    y = height/2.0 - (extents.height/2); 
    cairo_move_to (cr, x, y); 
    cairo_show_text (cr, unit); 

    cairo_select_font_face (cr, "Roboto", CAIRO_FONT_SLANT_NORMAL, 
       CAIRO_FONT_WEIGHT_BOLD); 
    cairo_set_font_size (cr, linewidth*1.3); 
    sprintf(pcTemp,"%.1f",value); 
    cairo_text_extents (cr, pcTemp, &extentsTemp); 
     x = width/2.0-(extentsTemp.width/2 + extentsTemp.x_bearing); 
     y = height/2.0 - extentsTemp.y_bearing; 
    cairo_move_to (cr, x, y); 
    cairo_show_text (cr, pcTemp); 

    cairo_select_font_face (cr, "Roboto Thin", CAIRO_FONT_SLANT_NORMAL, 
        CAIRO_FONT_WEIGHT_NORMAL); 
    cairo_set_font_size (cr, linewidth); 
    cairo_text_extents (cr, pcname, &extentsLabel); 
     x = width/2.0-(extentsLabel.width/2 + extentsLabel.x_bearing); 
     y = height/2.0 - extentsTemp.y_bearing - extentsLabel.y_bearing*1.20; 
    cairo_move_to (cr, x, y); 
    cairo_show_text (cr, pcname); 


    cairo_select_font_face (cr, "Roboto Thin", CAIRO_FONT_SLANT_NORMAL, 
         CAIRO_FONT_WEIGHT_NORMAL); 
    cairo_set_font_size (cr, linewidth*0.5); 
    sprintf(pcTemp,"%.1f",min); 
    cairo_text_extents (cr, pcTemp, &extentsTempMin); 
     x = width/2.0 - MIN (width, height)/2.0 + linewidth - (extentsTempMin.width/2 + extentsTempMin.x_bearing); 
     y = height/2.0 - extentsTempMin.y_bearing*1.20; 
    cairo_move_to (cr, x, y); 
    cairo_show_text (cr, pcTemp); 


    cairo_select_font_face (cr, "Roboto Thin", CAIRO_FONT_SLANT_NORMAL, 
         CAIRO_FONT_WEIGHT_NORMAL); 
     cairo_set_font_size (cr, linewidth*0.5); 
     sprintf(pcTemp,"%.1f",max); 
     cairo_text_extents (cr, pcTemp, &extentsTempMax); 
      x = width/2.0 + MIN (width, height)/2.0 - linewidth + (-extentsTempMax.width/2 + extentsTempMax.x_bearing); 
      y = height/2.0 - extentsTempMax.y_bearing*1.20; 
     cairo_move_to (cr, x, y); 
     cairo_show_text (cr, pcTemp); 
    return TRUE; 
} 

,其結果是this

GtkWidget *drawing_area = gtk_drawing_area_new(); 
    gtk_widget_set_size_request (drawing_area, 100, 100); 
    gtk_box_pack_start (GTK_BOX(gtk_builder_get_object(builder, "box30")),drawing_area,FALSE,TRUE,0); 

我創建了一個繪圖區域,並要求大小,但我沒有得到這個尺寸。 所以我的問題是:

  • 我怎麼能繪圖區(產生繪製事件?)內更新數據?

  • 爲什麼我不能請求繪圖區窗口小部件的大小?

受歡迎的意見。

回答

1

答到

1)每當你更新數據,迫使平局更新:

gtk_widget_queue_draw(GTK_WIDGET(drawing_area)) 

2)您可以請求的大小,但如果容器設置擴大,那麼小部件最終可能會擴展; set_size_request函數/方法將設置繪圖區將「擁有」的最小尺寸。從我們可以在代碼中看到的內容,繪圖區域位於GtkBox內。檢查展開和填充標誌。

提示1:您可以通過使用一個GtkFixed容器

提示2裏面你drawing_area測試set_size_request:嘗試創建一個自定義窗口小部件,這將是一個更好的解決方案。

+0

謝謝!問題是我的滾動窗口設置爲擴展,我認爲這不會導致任何問題。重新繪製我需要發送一些數據,如我發送繪製事件,我如何在繪製更新? –

+0

你有沒有任何例子如何創建一個簡單的自定義小部件與開羅? –

+0

@ R.Rodrigues您必須具有draw_area在draw回調之外表示的值。假設你有這個百分比。現在,在您的業務邏輯的某個地方,您需要更新該值,因此您可以使用percentage = x,然後您可以發出gtk_widget_queue_draw,並且draw方法將採用該值並重新繪製爲實際的新值。互聯網上散佈着大量關於創建自定義gtk小部件的信息。大部分是針對Gtk2的。檢查[這是爲C++](https://developer.gnome.org/gtkmm-tutorial/stable/sec-custom-widgets.html.en) –