2010-06-25 3 views
3

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

Вот код, 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-событие обратного вызова

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

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; 
} 

ответ

0

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

4

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

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

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

+0

Рисование выполняется внутри функции обратного вызова экспоненциального события, и оно работает с момента первоначального рисования. Дело в том, что мне нужно перерисовать GtkDrawingArea после щелчков мышью (я делал это в прошлом, не касался gtk какое-то время, поэтому я вроде ржавый) –

+0

@dailen: вызван ли 'onExposeEvent' после перерисовки планирования? Как вы запускаете основной цикл? – doublep

+0

Основной цикл довольно прост. Моя программа похожа на это: в mainWindow() - это весь код, относящийся к свойствам окна, сигнальным соединениям и всем другим виджетам (сыновьям окна верхнего уровня). Я просто хочу иметь возможность обновлять GtkDrawingArea после нескольких кликов, так как asfaik gtk_widget_queue_draw убеждается, чтобы вызвать обратный вызов «выставить-событие», перерисовать виджет. –

Смежные вопросы