1

Cairo と GTK での描画は初めてで、現在取り組んでいるプログラムでは、500x500 または 1000x1000 の円タイルを描画する必要があります。また、描画する前にやるべき作業がいくつかありますが、今は、円の色を変更するためのマウス操作を含む描画部分に集中しています。

したがって、タイリングは同じであり、時間の経過とともに円の色を変更する必要があります (すべての円)。サークルごとに確認して操作を行い、すべてのサークルを確認したら変更を表示する必要があります。このプロセスは、何度でも実行する必要があります。

現在、スクロールされたウィンドウでタイリングしていますが、これだけではスクロールに時間がかかります。前もって感謝します。私のコードは次のとおりです。

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

static void do_drawing(cairo_t *, GtkWidget *);
static int cellRadius=5;
static int cellDiameter=10;
static int latticeSideSize=500;

static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data){  
    do_drawing(cr, widget);  
    return FALSE;
}

static void do_drawing(cairo_t *cr, GtkWidget *widget)
{
  int i=0,j=0;
  GtkWidget *win = gtk_widget_get_toplevel(widget);

  int width, height;
  gtk_window_get_size(GTK_WINDOW(win), &width, &height);

  cairo_set_line_width(cr, .5);  
  cairo_set_source_rgb(cr, 0.69, 0.19, 0);
  cairo_save (cr);

  for(i=0;i<latticeSideSize;i++){

    for(j=0;j<latticeSideSize;j++){
      if(i%2 == 0){
        cairo_arc(cr, cellRadius + 2*cellRadius + j*cellDiameter, cellRadius + cellRadius + i*cellDiameter, cellRadius, 0, 2 * M_PI);
        cairo_stroke(cr);
      }else{
        cairo_arc(cr, cellRadius + cellRadius + j*cellDiameter, cellRadius + cellRadius + i*cellDiameter, cellRadius, 0, 2 * M_PI);
        cairo_stroke(cr);
      }

    }

  }
  cairo_restore (cr);
}

static void destroy( GtkWidget *widget, gpointer   data ){
    gtk_main_quit ();
}

int main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *scrolled_window;
  GtkWidget *darea;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
  scrolled_window = gtk_scrolled_window_new (NULL, NULL); 
  darea = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER(scrolled_window), darea);
  gtk_container_add(GTK_CONTAINER(window), scrolled_window);

  g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL);
  g_signal_connect(G_OBJECT(scrolled_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_widget_set_size_request( scrolled_window, 500, 500 );
  gtk_window_set_default_size(GTK_WINDOW(window), 1024, 800); 
  gtk_widget_set_hexpand( scrolled_window, TRUE );
  gtk_widget_set_vexpand( scrolled_window, TRUE );
  gtk_window_set_title(GTK_WINDOW(window), "HexaGrid");
  gtk_widget_set_size_request(darea,cellDiameter*latticeSideSize + 20,cellDiameter*latticeSideSize + 20);

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
  gtk_container_set_border_width(GTK_CONTAINER (scrolled_window), 10);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}
4

1 に答える 1

4

ここには 2 つの問題があります。まず、同じかなり要求の厳しい計算 (円) を 1 回の描画で 250000 回実行しているため、スクロールがスムーズであれば 1 秒あたり 1500 万円になります。これは現実的な要件ではありません。一度円を描いてから、CAIRO_EXTEND_REPEAT 拡張モードでサーフェス パターンと同じ結果を適用する必要があります。を使用してパターンの位置を設定し、cairo_translate()を使用cairo_set_source()して円パターンをソースとして設定し、cairo_rectangle()+cairo_fill()を使用して描画します。カイロのサンプルには、ビットマップを使用した例が含まれています。

いくつかの円を異なる色にする必要がある場合は、それらの一部またはすべてを「手動で」(繰り返し拡張モードを使用せずに)描くことができますが、円を何度も計算することを避けるために、パターンを使用することをお勧めします。

次に、複雑なウィジェットの場合、ウィジェット全体を描画するのではなく、ダーティ リージョンのみを描画するのが理にかなっています: draw-signal documentationを参照してください。

于 2014-03-16T11:36:49.900 に答える