【发布时间】:2015-06-22 21:03:13
【问题描述】:
我正在开发一个小型 GTK+ 程序,我在其中放置了 GtkDrawingArea。我用它是为了画一种比较具体的数据表示图,结果还是比较满意的。
问题是:“图形”有很多数据要处理,并且绘制信号的回调被频繁调用。最重要的是,每次将窗口 (GtkWindow/GtkContainer) 调整几个像素时都会调用它。为了避免过多地减慢应用程序的速度,我想在调整窗口大小时“暂停”绘制回调。我们可以想象整个区域会同时被一个灰色的矩形覆盖,或者类似的东西......
gboolean draw_callback(GtkWidget* widget, cairo_t* cr, gpointer data){
/* A lot of drawing with Cairo
* This is called WAY too often. */
}
int main(int argc, char* argv[]){
GtkBuilder* builder;
GtkWidget *window;
GtkWidget *draw_area;
gtk_init(&argc, &argv);
builder = gtk_builder_new_from_file("myapp.ui");
window = GTK_WIDGET(gtk_builder_get_object(builder, "main_window"));
draw_area = GTK_WIDGET(gtk_builder_get_object(builder, "draw_area"));
g_signal_connect(draw_area, "draw", G_CALLBACK(draw_callback), NULL);
gtk_widget_show_all(GTK_WIDGET(window));
g_object_unref(builder);
gtk_main();
return 0;
}
注意:调整窗口大小后仍必须执行回调(发生这种情况时需要重新计算一些坐标)。我只是想在 调整窗口大小时避免它。
我的第一个想法是将回调连接到 check-resize 事件,在该事件中可以设置和取消设置布尔值,因为窗口被抓取和释放(同时调整大小):
gboolean resizing = false;
void resize_callback(GtkContainer* container, gpointer data){
/* Set "resizing"...
* Is the window being grabbed? Released? */
}
gboolean draw_callback(GtkWidget* widget, cairo_t* cr, gpointer data){
if(resizing){
/* Draw a gray overlay or something if necessary... */
return true;
}
/* Draw the actual stuff here... */
}
int main(int argc, char* argv[]){
GtkWidget *window;
GtkWidget *draw_area;
// ...
g_signal_connect(window, "check-resize", G_CALLBACK(resize_callback), NULL);
g_signal_connect(draw_area, "draw", G_CALLBACK(draw_callback), NULL);
// ...
}
但是这个事件并不适合我,因为它不会在窗口被抓取/释放时触发(仅当它的大小实际改变时)。
有没有办法在窗口被抓取和释放(调整大小)时得到通知?或者在调整窗口大小时是否有更好的方法来暂停/简化对draw_callback 的调用?
【问题讨论】:
标签: c gtk3 window-resize