2010-08-11 8 views
1

여기 내 코드입니다 :GTK + 위젯의 이벤트가 오랜 시간 후에 왜 멈추게 될까요? GTK + 버그입니까?

#include <gtk/gtk.h> 

static int counter = 0; 
static PangoLayout* layout; 
static GdkGC* gc1; 
static GdkGC* gc2; 
//**/static GMutex* mu; 

static gboolean on_expose_event(GtkWidget* widget, GdkEventExpose* event) 
{ 
    gchar the_string[20]; 

    //**/g_mutex_lock(mu); 
    gdk_draw_rectangle(GDK_DRAWABLE(widget->window), gc1, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); 
    snprintf(the_string, 20, "%d", counter); 
    pango_layout_set_text(layout, the_string, -1); 
    gdk_draw_layout(GDK_DRAWABLE(widget->window), gc2, 180, 120, layout); 
    //**/g_mutex_unlock(mu); 

    g_print ("."); 
    return FALSE; 
} 

gpointer func(gpointer data) 
{ 
    //**/g_usleep(10000); 
    GdkWindow* window = GDK_WINDOW(data); 
    while(TRUE) 
    { 
     gdk_window_invalidate_rect(window, NULL, FALSE); 
     //**/gdk_window_process_updates(window, FALSE); 
     if(counter % 100 == 0) g_print("X"); 
     g_usleep(10); 
     ++counter; 
    } 
    return FALSE; 
} 

int main(int argc, char** argv) 
{ 
    GtkWidget* window; 
    GtkWidget* drawer; 
    GdkColormap* colormap; 
    GdkColor color; 

    g_thread_init(NULL); 
    gdk_threads_init(); 
    gtk_init(&argc, &argv); 

    //:Create widgets and 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    drawer = gtk_drawing_area_new(); 
    gtk_widget_set_size_request(drawer, 400, 300); 
    gtk_container_add(GTK_CONTAINER(window), drawer); 
    //. 

    gtk_widget_show_all(window); 

    //:Initializing Graphic Contexts 
    colormap = gtk_widget_get_colormap(GTK_WIDGET(drawer)); 
    layout = gtk_widget_create_pango_layout(GTK_WIDGET(drawer), NULL); 
    gc1 = gdk_gc_new(GDK_DRAWABLE(GTK_WIDGET(drawer)->window)); 
    gc2 = gdk_gc_new(GDK_DRAWABLE(GTK_WIDGET(drawer)->window)); 
    gdk_color_parse("#000", &color); 
    gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE); 
    gdk_gc_set_background(gc1, &color); 
    gdk_color_parse("#fff", &color); 
    gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE); 
    gdk_gc_set_foreground(gc2, &color); 
    //. 

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

    //**/mu = g_mutex_new(); 
    //Run the problematic thread! 
    g_thread_create(func, GTK_WIDGET(drawer)->window, TRUE, NULL); 

    gdk_threads_enter(); 
    gtk_main(); 
    gdk_threads_leave(); 

    //**/g_mutex_free(mu); 
    return 0; 
} 

그것은 다중 스레드 프로그램, 그리고 그렇게 특별한 아무것도하지 않았다! GtkDrawingArea가 메인 스레드 (GTK + 메인 루프)에서 자신을 다시 그리도록 강요합니다.

내 문제 (또는 GTK + 문제!)는 장시간 (0.5, 1 또는 4 분!) 실행 한 후에 노출 이벤트가 작동하지 않습니다. 전체 크기를 조정할 때까지 내 요청에 응답하지 않습니다. 창문!)! 이 상황을 확인하려면 코드를 컴파일하고 실행하십시오. 도움이 될만한 인쇄 명령을 추가했습니다! 하지만 내 작은 경험 때문에 문제를 감지 할 수 없습니다.

나는이 프로그램이 거의 항상 컨텍스트를 다시 그릴 수 있기를 바랐지만, 그렇지 않았다. 이 문제를 해결하려면 어떻게해야합니까? 아마 GTK + 개발자에게 버그를보고해야합니까? 내가 데비안 + GCC + GTK2.20

답변

3

대부분의 경우, 당신은 gdk_threads_enter와() 호출하여 gdk_window_invalidate_rect 묶어야합니다()/gdk_threads_leave() 쌍을 사용하고

. gtk 및 스레드에 대한 자세한 내용은 gdk threads을 참조하십시오. 그 예를보세요.

+0

감사합니다. 이제 영원히 작동합니다. :) –

0

콜백과 함께 g_timeout_add을 사용하고 을 사용하지 말아야합니다.은 UI가 엉망인 두 번째 스레드를 사용합니다.