当(重新)在expose_event之后绘制CAIRO矩形时,我发现双缓冲可以防止屏幕闪烁。不幸的是,当调整窗口框架大小时,双缓冲区似乎在屏幕上“悬挂”为阴影。将双缓冲设置为FALSE,删除阴影但会使复杂的绘图闪烁。
如果我将“无效”整个新调整大小的窗口区域(在公开事件中),问题就解决了,但是曝光事件不断激发新的重绘请求。
如何在双缓冲上下文中调整GDK剪辑区域的大小?
非常感谢
我使用的程序代码检测问题的原因:
#include <stdio.h>
#include <cairo.h>
#include <gtk/gtk.h>
static gboolean on_expose_event (GtkWidget *widget,
GdkEventExpose *event ,
gpointer data)
{
cairo_t *cr;
int width, height, kwadrant;
cr = gdk_cairo_create (widget->window);
gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
cairo_rectangle(cr, 0.0, 0.0, width, height);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.5);
cairo_fill(cr);
if (width < height)
kwadrant = 0.8 * width;
else
kwadrant = 0.8 * height;
cairo_set_line_width(cr, 1);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_rectangle(cr, (width - kwadrant)/2, (height - kwadrant)/2, kwadrant, kwadrant);
cairo_stroke(cr);
cairo_destroy(cr);
return TRUE;
}
void frame_callback(GtkWindow *window,
GdkEvent *event,
gpointer data)
{
char buff [50];
sprintf (buff, "%i X %i", event->configure.width,
event->configure.height);
gtk_window_set_title(window, buff);
return;
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER (window), darea);
gtk_widget_set_app_paintable(window, TRUE);
gtk_widget_set_double_buffered(window, TRUE);
g_signal_connect(G_OBJECT(window), "expose-event",
G_CALLBACK(on_expose_event), NULL);
g_signal_connect(G_OBJECT(window), "configure-event",
G_CALLBACK(frame_callback), NULL);
g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window));
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE);
gtk_widget_show (window);
gtk_main();
return 0;
}
=========稍后补充:
经常发生: 在搜索有效解决方案的天数后,我发布了此消息。过了一会儿,我试图在EXPOSE事件之外隔离“触发剪辑”并替换所有
gtk_widget_queue_draw (widget);
使用
进行调用void request_redraw (GtkWidget *widget)
{
GdkRectangle rect;
int width, height;
gtk_window_get_size (GTK_WINDOW(window), &width, &height);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
gdk_window_invalidate_rect (gtk_widget_get_window(widget), &rect, TRUE);
gtk_widget_queue_draw (widget);
return;
}
这允许我保持双缓冲,避免屏幕闪烁并重新绘制与调整大小的帧/窗口对应的整个区域。
这是一个正确的解决方案还是有更好的方法?
抱歉提出了不必要的问题