快速绘制瓷砖GTK和Cairo

快速绘制瓷砖GTK和Cairo,gtk,drawing,cairo,tiling,Gtk,Drawing,Cairo,Tiling,我是Cairo和GTK绘图新手,我正在开发的程序需要绘制500x500或1000x1000的圆形瓷砖。此外,在绘图之前还有一些工作要做,但现在我主要关注绘图部分,这将涉及鼠标交互来更改任何圆的颜色 因此,瓷砖是相同的,随着时间的推移,这些圆必须改变它们的颜色(全部)。我必须检查每个圆圈并执行操作,检查完所有圆圈后,我必须显示更改。此过程必须执行任意次数 现在,我有一个滚动窗口的平铺,但就是这样,它需要大量的时间滚动。提前谢谢。下面是我的代码: #include <cairo.h> #

我是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;
}
#包括
#包括
#包括
静态空心图(cairo_t*,GtkWidget*);
静态单位半径=5;
静态内径=10;
静态int latticeSideSize=500;
静态gboolean on_draw_事件(GtkWidget*小部件、cairo_t*cr、gpointer用户_数据){
do_图纸(cr、小部件);
返回FALSE;
}
静态void do_图形(cairo_t*cr、GtkWidget*widget)
{
int i=0,j=0;
GtkWidget*win=gtk_widget_get_toplevel(widget);
int宽度、高度;
gtk_窗口尺寸(gtk_窗口(win)、宽度和高度);
cairo\u set\u line\u width(cr,.5);
cairo_set_source_rgb(cr,0.69,0.19,0);
开罗储蓄银行(cr);

对于(i=0;i这里有两个问题。首先,你正在做同样的相当苛刻的计算(圆圈)每次绘制250000次,因此如果滚动平滑,每秒可旋转1500万圈:这不是一个现实的要求。您可能需要旋转一次,然后使用CAIRO\u EXTEND\u REPEAT EXTEND模式应用与曲面图案相同的结果。您可以使用
CAIRO\u translate()设置图案的位置
并使用
cairo\u set\u source()
将圆形图案设置为源,然后使用
cairo\u rectangle()
+
cairo\u fill()
绘制。cairo示例包含

如果某些圆需要使用不同的颜色,则可以“手动”(无需重复扩展模式)绘制部分或全部圆,但使用图案可能仍然是避免多次计算圆的好方法


其次,对于复杂的小部件,不绘制整个小部件,而只绘制脏区域是有意义的:请参见。

这里有两个问题。首先,您正在进行同样的相当苛刻的计算(圆圈)每次绘制250000次,因此如果滚动平滑,每秒可旋转1500万圈:这不是一个现实的要求。您可能需要旋转一次,然后使用CAIRO\u EXTEND\u REPEAT EXTEND模式应用与曲面图案相同的结果。您可以使用
CAIRO\u translate()设置图案的位置
并使用
cairo\u set\u source()
将圆形图案设置为源,然后使用
cairo\u rectangle()
+
cairo\u fill()
绘制。cairo示例包含

如果某些圆需要使用不同的颜色,则可以“手动”(无需重复扩展模式)绘制部分或全部圆,但使用图案可能仍然是避免多次计算圆的好方法


其次,对于复杂的小部件,不绘制整个小部件而只绘制脏区域是有意义的:请参见。

谢谢,这是有意义的。我今天就来试试。谢谢。谢谢,这是有意义的。我今天就来试试。谢谢。