1

这是我关于堆栈溢出的第一个问题。

从 Arch Linux 迁移到 Ubuntu 11.10 后,我面临一个问题。每当单击活动小部件(即按钮等)时,我遇到的问题就是小部件消失。如果单击活动按钮,则所有其他小部件都会消失,但单击的按钮除外。然后将鼠标移到消失的按钮上会使它们再次出现。但是单击该按钮会导致其余小部件再次消失。

我已经举了一个我面临的问题的小例子,不确定它是 gtk 还是 Cairo 重绘问题。但是,如果我从代码中删除 cairo 图形,则不会出现此问题。

#include <gtk/gtk.h>
#include <math.h>
#include <cairo.h>
//gcc -Wall -Werror -g repaint_problem.c -o repaint_problem `pkg-config --cflags --libs gtk+-2.0`

void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata)
{
    GdkScreen *screen = gtk_widget_get_screen(widget);
    GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);

    if (!colormap)
    {
        printf(" Your screen does not support alpha channels! >:-P\n");
        colormap = gdk_screen_get_rgb_colormap(screen);
    }

    gtk_widget_set_colormap(widget, colormap);
}

gboolean W_expose(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
{
    cairo_t *cr = gdk_cairo_create(widget->window);
    cairo_pattern_t *pat1;

    cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */

    /* draw the background */
    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
    cairo_paint (cr);

    gshort x1 , y1 , x2 , y2;
    x1=0;
    y1=0;
    x2=400;
    y2=200;

    cairo_move_to(cr, x1+6, y1);
    cairo_arc(cr, x2-9, y1+10, 10, 270 * (M_PI / 180), 360 * (M_PI / 180));
    cairo_arc(cr, x2-9, y2-10, 10, 0 * (M_PI / 180), 90 * (M_PI / 180));
    cairo_arc(cr, x1+10, y2-10, 10, 90 * (M_PI / 180), 180 * (M_PI / 180));
    cairo_arc(cr, x1+10, y1+10, 10, 180 * (M_PI / 180), 270 * (M_PI / 180));
    cairo_stroke_preserve(cr);
    pat1 = cairo_pattern_create_linear(0, y1, 0, y2);
    cairo_pattern_add_color_stop_rgba(pat1, 0.05, 0.35, 0.38, 0.82, 1);
    cairo_pattern_add_color_stop_rgba(pat1, 0.9,0.67, 0.78, 0.97 ,0.9);
    cairo_set_source(cr, pat1);
    cairo_fill(cr);

    cairo_pattern_destroy(pat1);    
    cairo_destroy(cr);
    g_print("redrawing\n");
    return FALSE;
}


int main (int argc, char *argv[])
{
  GtkWidget *window, *fixed, *button[3];
  gtk_init (&argc, &argv);
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Cairo Dissappearing Button Act :-P");
  gtk_container_set_border_width (GTK_CONTAINER (window), 0);
  gtk_widget_set_size_request (window, 400, 200);

    // commenting out the line below will stop the cairo repainting and also stop the problem!
    g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(W_expose), NULL);

    g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);
    gtk_widget_set_app_paintable(window, TRUE);
    screen_changed(window, NULL, NULL);

  fixed = gtk_fixed_new ();

    gint i;
    for(i = 0 ; i<3 ; i++)
    {
        button[i]=gtk_button_new();
        gtk_widget_set_size_request (button[i], 40, 40); 
        gtk_fixed_put (GTK_FIXED (fixed), button[i], (i+1)*50, 40);
    }

  gtk_container_add (GTK_CONTAINER (window), fixed);

  g_signal_connect (G_OBJECT (window), "destroy",G_CALLBACK (gtk_main_quit), NULL);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
}

提前致谢

4

0 回答 0