Перерисовка виджета в Gtk - PullRequest
3 голосов
/ 25 июня 2010

Я пытаюсь перерисовать GtkDrawingArea с помощью функции gtk_widget_queue_draw, но виджет не перерисовывается.

Вот код, gtk_widget_queue_draw находится внутри функции обратного вызова кнопки-нажатия-события.

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

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 (оба внутри функции, которая создает окно верхнего уровня).

  g_signal_connect(G_OBJECT(board),"expose-event",G_CALLBACK(onExposeEvent),NULL);
  g_signal_connect(G_OBJECT(board),"button-press-event",G_CALLBACK(click),window);

Основная функция.

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

    mainWindow(); //Creates the main window

    gtk_main();

    return 0;
}

Ответы [ 2 ]

4 голосов
/ 25 июня 2010

Невозможно однозначно сказать, что не так, поскольку вы не вставили весь соответствующий код.В любом случае, я думаю, что могут возникнуть две ошибки / недоразумения, которые приведут к вашей проблеме.

  • Вы должны рисовать только в expose-event обработчике сигналов.Хотя рисование снаружи возможно, такое рисование не будет обновлено и может быть полностью потеряно по ряду причин, включая такое самозапускаемое перерисовывание.
  • Перерисовка произойдет асинхронно .Т.е. в другой основной цикл запустить.Это может быть проблематично, если вы запускаете основной цикл нестандартным способом, например, используя gtk_events_pending() / gtk_main_iteration().

Наконец, убедитесь, что board на самом деле является виджетом, который вы намереваетесьперерисовывать.Возможно, вы передали неверные данные пользователя при подключении click().

0 голосов
/ 27 июня 2010

Нашел ответ, нет ничего плохого в коде gtk. Код, специфичный для моей программы, вызывал ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...