我正在开发一个小型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
的调用?
答案 0 :(得分:1)
在鼠标按钮关闭时,请考虑阻止绘制回调。保存回调ID:
draw_callback_id = g_signal_connect(draw_area, "draw",
G_CALLBACK(draw_callback), NULL);
当检测到按下按钮的信号时,执行
g_signal_handler_block(draw_area, draw_callback_id);
当然,在按钮释放事件之后:
g_signal_handler_block(draw_area, draw_callback_id);
然后,您可以手动触发重绘事件。要进行优化,您可以使用gtk_widget_queue_draw_region()
调用,该调用仅重绘指定的矩形。
另一种可能性(尽管我还没试过)可能只是在调整大小或移动时绘制窗口边框。窗口管理器(XFCE)有这个选项,但我还没有看到如何从GTK内部做到这一点。