开发者

Redrawing a widget in Gtk

I'm trying to redraw a GtkDrawingArea using the gtk_widget_queue_draw function, but the widget is not redrawing.

Here's the code, the gtk_widget_queue_draw is inside a button-press-event callback function.

static gboolean click(GtkWidget *board,GdkEventButton *event,gpointer parentWindow){
    static int origen = -1;
    static int destino = -1;

    if(origen == -1){
        mapeo(&origen, event->x, event->y);
    }else{
       mapeo(&destino, event->x, event->y);
    if(!movimiento_fichas(JUGADOR_DOS, origen - 1, destino - 1)){
        dialogoMovInvalido(parentWindow); //displays a warning dialog
        g_print("%d %d", origen, destino); //debugging console output
        origen = -1; destino = -1;
    }else{
        g_print("%d %d", origen, destino); //debugging console output
        gtk_widget_queue_draw(board); //Here's where the redrawing is supossed to occur.
       }
    }

    return 0;
}

Expose-event callback

static gboolean onExposeEvent(GtkWidget *widget,GdkEventExpose *event,gpointer data){
    cairo_t *cr;
    cairo_surface_t *fondo;
    cairo_surface_t *ficha_roja;
    cairo_surface_t *ficha_blanca;

gint i,j;

cr = gdk_cairo_create(widget->window);

fondo = cairo_image_surface_create_from_png("interfaz.png");
ficha_roja = cairo_image_surface_create_from_png("ficha_roja.png");
ficha_blanca = cairo_image_surface_create_from_png("ficha_blanca.png");

cairo_set_source_surface(cr, fondo, 0, 0);
cairo_paint(cr);

for(i=0; i<24; i++){
    if(tablero[i].player == JUGADOR_UNO){
        cairo_set_source_surface(cr, ficha_blanca, posiciones[i].x, posiciones[i].y);
        for(j=1; j<=tablero[i].num; j++){
            cairo_paint(cr);
            cairo_set_source_surface(cr, ficha_blanca, posiciones[i].x, posiciones[i].y);
            if(i < 12)
                cairo_set_source_surface(cr, ficha_blanca, posiciones[i].x, posiciones[i].y - (j*25));
            else
                cairo_set_source_surface(cr, ficha_blanca, posiciones[i].x, posiciones[i].y + (j*25));
        }
    }else if(tablero[i].player == JUGADOR_DOS){
        cairo_set_source_surface(cr, ficha_roja, posiciones[i].x, posiciones[i].y);
        for(j=1; j<=tablero[i].num; j++){
            cairo_paint(cr);
            if(i < 12)
                cairo_set_source_surface(cr, ficha_roja, posiciones[i].x, posiciones[i].y - (j*25));
            else
                cairo_set_source_surface(cr, ficha_roja, posiciones[i].x, posiciones[i].y + (j*25));
        }
    }
}

cairo_destroy(cr);

return 0;
}

Expose-event & button-press-event connections (both inside the function that creates the top level window).

  g_signal_connect(G_OBJECT(board),"expose-event",G_CALLBACK(onExposeEvent),NULL);
  g_signal开发者_Go百科_connect(G_OBJECT(board),"button-press-event",G_CALLBACK(click),window);

Main function.

int main(int argc, char *argv[]){
    gtk_init(&argc, &argv);

    mainWindow(); //Creates the main window

    gtk_main();

    return 0;
}


It is not possible to tell conclusively what's wrong, since you didn't paste all the relevant code. Anyway, I think there might be two errors/misunderstanding that result in your problem.

  • You should draw only in expose-event signal handler. While drawing outside it is possible, such drawing will not be updated and might get completely lost for any number of reasons, including such self-initiated redrawing.
  • Redrawing will happen asynchronously. I.e. in a different main loop run. This might be problematic if you run the main loop in a non-standard way, e.g. using gtk_events_pending()/gtk_main_iteration().

Finally, check that board is actually the widget you intend to redraw. Might be that you passed wrong user data when connecting click().


Found the answer, there's nothing wrong with the gtk code. Code specific to my program was causing the error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜