gpt4 book ai didi

c - 如何在调整窗口大小时暂停 GtkDrawingArea 绘制回调?

转载 作者:太空狗 更新时间:2023-10-29 15:40:31 25 4
gpt4 key购买 nike

我正在开发一个小型 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 事件,其中可以设置和取消设置 bool 值,因为窗口被抓取和释放(同时调整大小时):

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 的调用?

最佳答案

考虑在按下鼠标按钮时阻止绘图回调。保存回调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 内部执行此操作。

关于c - 如何在调整窗口大小时暂停 GtkDrawingArea 绘制回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30989762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com