GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Tue Jul 29, 2014 10:43 am

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Frequently redrawing of one part of a bigger graphic
PostPosted: Sun Apr 07, 2013 6:28 pm 
Offline

Joined: Sat Apr 06, 2013 7:57 pm
Posts: 1
Hello,

I'm new at this board and a beginner in GTK+3 (with C).

I want to build a instrument such like a clock (but not the same - it's a bit special). My first result works with one thread. But at some incoming data frequencies the display starts bucking. Than I take two threats. One threat for the data work, one threat displaying the results. For the comunication I use pthread-mutexes. Now the programm runs fine, but it needs a much CPU. I found the reason at my graphical output. For these I used:

Code:
   g_signal_connect(G_OBJECT(area_radar), "draw",
                    G_CALLBACK(on_draw_event), data);

I saw that the program runs in a very fast loop.

The main questions are:
    1) How is the right structure to redraw the graphic with a frequency at 10 to 25Hz or only at changing of the affected values?
    2) How to implement that only affected graphics will recalculated?


For this I tryed the following approach:
Two pixbufs are drawn at startup. After that only the arrow will frequently redrawed.

I hope you can help me.

Code:
/*
   gcc -Wall -ansi -Werror -pedantic -g main_14.c \
   `pkg-config --libs --cflags gtk+-3.0` -lm -lpthread
*/

#include <cairo-svg.h>
#include <gtk/gtk.h>
#include <math.h>
#include <stdio.h>

#define M_PI 3.14159

int cnt_ca=0, cnt_cb=0, cnt_queue=0;
double winkel = 0;


/* only for visualising */
enum pstat_t {ca, cb, queue};
enum pstat_t pstat;

void cnt(enum pstat_t v){
   
   switch( v )
   {
      case ca:
         cnt_ca++;
         break;
      case cb:
         cnt_cb++;
         break;
      case queue:
         cnt_queue++;
         break;
   }      
   fprintf(stderr,"\r ca=%i | cb=%i | queue=%i",
           cnt_ca, cnt_cb, cnt_queue);
}


gint close_prog(){

   /* beendet GTK */
   printf("\nProgramm wird beendet.\n");
   gtk_main_quit();
   gdk_flush();
      
   return(TRUE);
}

GtkWidget *set_window_options(GtkWidget *window){

   /* Fenster einstellen */
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

   /* Fensterposition */
   gtk_window_set_position(GTK_WINDOW(window),
                           GTK_WIN_POS_CENTER);
   
   /* Fenstergröße */
   gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);

   return window;
}


GdkPixbuf * create_backround(GdkPixbuf *pix){
   
   cairo_t * cr;
   cairo_surface_t *surface;

   cnt(pstat=cb);
   
   /* erzeugung einer Zeichenoberfläche */
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 100, 100);
   /* erzeugt ein Cairo-Object mit der Zeichenoberfläche als Ziel */
   cr = cairo_create(surface);

   /* ein bisschen malen */   
   cairo_arc(cr, 50, 50, 45, 0, 2 * M_PI);
   cairo_stroke_preserve(cr);
   
   /* das Cairo-Object wird nicht mehr gebraucht */
   cairo_destroy(cr);
   
   /* Zeichenfläche wird in den Pixbuf (Zeichnung nicht sichtbar) übertragen */
   /* die ersten zwei Koordinaten sind der Referenzpunkt im surface und werden
      an dem Ursprung (0;0) von pix ausgerichtet */
   pix = gdk_pixbuf_get_from_surface(surface, -50, -50, 200, 200);   

   /* die Zeichenfläche wird nicht mehr gebraucht */
   cairo_surface_finish (surface);

   return pix;
}


GdkPixbuf * create_arrow(GdkPixbuf *pix){

   cairo_t * cr;
   cairo_surface_t *surface;

   cnt(pstat=ca);
   
   winkel+= M_PI/10;

   /* erzeugung einer Zeichenoberfläche */
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 100, 100);
   /* erzeugt ein Cairo-Object mit der Zeichenoberfläche als Ziel */
   cr = cairo_create(surface);

   /* ein bisschen malen */   
   cairo_move_to(cr, 50, 50);
   cairo_rel_line_to(cr, sin(winkel)*50, -cos(winkel)*50);
   cairo_stroke_preserve(cr);

   /* das Cairo-Object wird nicht mehr gebraucht */
   cairo_destroy(cr);
   
   /* Zeichenfläche wird in den Pixbuf (Zeichnung nicht sichtbar) übertragen */
   /* die ersten zwei Koordinaten sind der Referenzpunkt im surface und werden
      an dem Ursprung (0;0) von pix ausgerichtet */
   pix = gdk_pixbuf_get_from_surface(surface, -50, -50, 200, 200);   

   /* die Zeichenfläche wird nicht mehr gebraucht */
   cairo_surface_finish (surface);

   return pix;
}

int main (int argc, char **argv){

   GtkWidget *window = NULL;
   GtkWidget *image_a;
   GtkWidget *image_b;
   GtkWidget *fixed;

   GdkPixbuf *pix_a = NULL;
   GdkPixbuf *pix_b = NULL;

   /* Initialisierung von GTK */
   gtk_init(&argc, &argv);

   fixed = gtk_fixed_new();

   /* neues Fenster erzeugen und einstellen */
   window = set_window_options(window);   
   
   /* einen Hintergrund erzeugen */   
   pix_b = create_backround(pix_b);
   pix_a = create_arrow(pix_a);

   /* der Inhalt von pix wird als Image(GtkWidget) ausgegeben */
   image_a = gtk_image_new_from_pixbuf(pix_a);
   image_b = gtk_image_new_from_pixbuf(pix_b);

   /* Anordnen der einzelnen Bilder */
   gtk_fixed_put(GTK_FIXED(fixed), image_a, 0, 0);
   gtk_fixed_put(GTK_FIXED(fixed), image_b, 0, 0);
   
   /* Das Bild wird über einen Container an das Fenster gebunden */
   gtk_container_add(GTK_CONTAINER(window), fixed);    

   /* Implementierung der Call-back-Funktionen */
     g_signal_connect(window, "destroy",
                    G_CALLBACK(close_prog), NULL);

   g_timeout_add(500, (GSourceFunc)gtk_widget_queue_draw, window);

   /* zeige alle Fenster */
   gtk_widget_show(image_a);
   gtk_widget_show(image_b);
   gtk_widget_show(fixed);
   gtk_widget_show(window);

   /* GTK-Hauptschleife */
   gtk_main();

   return 0;
}


^^^ This is a short example ^^^


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group