我是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;
}
答案 0 :(得分:4)
这里有两个问题。首先,你正在进行相同的相当苛刻的计算(圆圈)每次绘制250000次,如果滚动平滑,则每秒1500万次圆圈:这不是一个现实的要求。您可能应该执行一次圆,然后使用CAIRO_EXTEND_REPEAT扩展模式将相同的结果应用于曲面模式。您可以使用cairo_translate()
设置模式的位置,并使用cairo_set_source()
将圆形模式设置为源,然后使用cairo_rectangle()
+ cairo_fill()
来绘制模式。开罗样本包含example using a bitmap。
如果某些圆圈需要使用不同颜色,您可以“手动”绘制部分或全部颜色(不使用重复延伸模式)但是使用图案仍然是避免多次计算圆圈的好主意。
其次,对于复杂的小部件,不绘制整个小部件而只绘制脏区域是有意义的:请参阅draw-signal documentation。