2017-06-21 4 views
0

Ich benutze Cairo, um einige kreisförmige Widget wie this zeichnen.Wie redraw Text mit Kairo mit GTK +

Ich verwendete "Zeichnen" -Ereignis des Zeichnungsbereichs, um alle das Widget zu zeichnen, aber ich weiß nicht, wie Sie Daten im Widget aktualisieren. Dies ist der Code, den ich mache:

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; 
} 

und das Ergebnis ist 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); 

ich einen Zeichenbereich erstellen und die Größe fordern, aber ich nicht bekommen, diese Größe. Also meine Frage lautet:

  • Wie kann ich Daten in einem Zeichenbereich aktualisieren (erzeugen ein Unentschieden Ereignis ??)?

  • Warum kann ich keine Größe des Zeichnungsbereich-Widgets anfordern?

Meinungen sind willkommen.

Antwort

1

Antwort

1) Jedesmal, wenn man Daten aktualisieren, zwingt ein Unentschieden Update mit:

gtk_widget_queue_draw(GTK_WIDGET(drawing_area)) 

2) Sie können eine Größe verlangen aber, wenn der Behälter gesetzt zu erweitern, dann kann das Widget schließlich erweitern; Die Funktion set_size_request/method legt die Mindestgröße fest, die der Zeichenbereich "haben" soll. Von dem, was wir in Ihrem Code sehen können, befindet sich der Zeichenbereich in einer GtkBox. Überprüfen Sie die Erweitern- und Füllen-Flags.

Tipp 1: Sie haben die set_size_request, indem Sie Ihre drawing_area in einem Container GtkFixed testen

Tipp 2: Versuchen Sie, eine benutzerdefinierte Widget zu erstellen, wäre es eine bessere Lösung.

+0

Danke! Das Problem ist, dass mein Scroll-Fenster auf erweitern eingestellt ist, und ich dachte, dass kein Problem verursacht. Um neu zu zeichnen, muss ich einige Daten senden, wie ich ein Draw-Event einschicke, wie kann ich ein Draw-Update machen? –

+0

Haben Sie ein Beispiel, wie Sie mit cairo ein einfaches benutzerdefiniertes Widget erstellen können? –

+0

@ R.Rodrigues Sie müssen die Werte haben, die drawing_area außerhalb des Zeichnungsrückrufs darstellt. Nehmen wir an, Sie haben den Prozentsatz. Nun müssen Sie irgendwo in Ihrer Geschäftslogik diesen Wert aktualisieren, also geben Sie prozentual = x an, dann können Sie eine gtk_widget_queue_draw ausgeben, und die draw-Methode wird diesen Wert übernehmen und auf den tatsächlichen neuen Wert neu zeichnen. Im Internet gibt es viele Informationen über das Erstellen von benutzerdefinierten gtk-Widgets. Die meisten sind für Gtk2. Überprüfen Sie [dies für C++] (https://developer.gnome.org/gtkmm-tutorial/stable/sec-custom-widgets.html.en) –