2013-08-25 62 views
0

AM GTK和GLIB很新,我只是試圖顯示一個圖像,然後調用disptext函數。 但是當disptextpage功能從主直接稱它的工作原理,但是當我創建一個線程可以調用它disptextpage卡在GTK代碼在線程中調用時掛起@ gtk_container_add

gtk_container_add(GTK_CONTAINER(window), textv); 

,永不回來。 什麼是我commiting

請指導錯誤:下面是示例代碼:

#include <stdio.h> 
    #include <glib.h> 
    #include <gtk/gtk.h> 
    //#include "dispimage.h" 
    #include <windows.h> 
    #define sleep(n) Sleep(1000 * n) 
    GtkWidget* window; 
    void dispInit(int argc, char* argv[]); 
    void dispInfoPage(char* fileName, int duration); 


    gpointer main_callback(gpointer data) 
    { 
     gtk_main(); 
     return 0; 
    } 

    void dispInit(int argc, char* argv[]) 
    { 
     gdk_threads_init(); 
     gdk_threads_enter(); 
     printf("Initializing the display library\n"); 
     gtk_init(&argc, &argv); 
     window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
     gtk_window_resize(GTK_WINDOW(window), 640, 480); 
     gtk_window_set_default_size(GTK_WINDOW(window), 640, 480); 
     gtk_widget_realize(window); 
     gtk_window_set_decorated(GTK_WINDOW(window), FALSE); 
     g_thread_create(main_callback, NULL, FALSE, NULL); 
     gdk_threads_leave(); 
    } 

    void dispInfoPage(char* fileName, int duration) 
    { 
     int index; 
     gdk_threads_enter(); 
     printf("Initializing dispInfoPage\n"); 
     destroyWidget(); 
     printf("Initializing dispInfoPage1\n"); 
     GtkWidget *image; 
     image = gtk_image_new_from_file(fileName); 
     printf("Initializing dispInfoPage2\n"); 
     gtk_container_add(GTK_CONTAINER(window), image); 
     gtk_widget_show(image); 
     gtk_widget_show(window); 
     printf("Initializing dispInfoPage4\n"); 
     printf("Initializing dispInfoPage5\n"); 
     gdk_threads_leave(); 
     printf("Initializing dispInfoPage6\n"); 
    } 

    void destroyWidget() 
    { 
     GList *children, *iter; 
     struct WidgetsAlive *temp, *prev, *next, *depTemp; 
     children = gtk_container_get_children(GTK_CONTAINER(window)); 
     for(iter = children; iter != NULL; iter = g_list_next(iter)){ 
      gtk_container_remove(GTK_CONTAINER(window),GTK_WIDGET(iter->data)); 
      printf("Deleting Widget\n"); 
     } 
     g_list_free(iter); 
     g_list_free(children); 

    } 


    int dispTextPage(char* fileName, int isJustifyCenter) 
    { 
     int index; 
     GtkWidget *textv; 
     GdkWindow *textv_window; 
     GdkPixmap *pixmap = NULL; 
     GtkTextBuffer *textBuffer; 
     gdk_threads_enter(); 
     GdkColor color; 
     char debugBuf[128] = { '\0' }; 
     char newfName[100]={'\0'}; 
     char ext[4]={'\0'}; 
     char temp[100]={'\0'}; 
     int i; 
     FILE * fd; 
     destroyWidget(); 
     textBuffer = gtk_text_buffer_new(NULL); 
     textv = gtk_text_view_new_with_buffer(textBuffer); 
     gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textv), 22); 
     gtk_text_view_set_right_margin(GTK_TEXT_VIEW(textv), 20); 
     gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(textv),1); 
     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textv), GTK_WRAP_CHAR); 
     if (isJustifyCenter == 1) 
     { 
      gtk_text_view_set_justification(GTK_TEXT_VIEW(textv), GTK_JUSTIFY_CENTER); 
     } 
     else 
     { 
      gtk_text_view_set_justification(GTK_TEXT_VIEW(textv), GTK_JUSTIFY_LEFT); 
     } 
     gtk_text_view_set_editable(GTK_TEXT_VIEW(textv), FALSE); 
     gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textv), FALSE); 
     printf("tttt0"); 
     gtk_container_add(GTK_CONTAINER(window), textv); 
     printf("tttt1"); 
     textv_window = gtk_text_view_get_window (GTK_TEXT_VIEW (textv), 
               GTK_TEXT_WINDOW_TEXT); 
     gdk_color_parse ("#68604d", &color); 
     pixmap = gdk_pixmap_create_from_xpm ((GdkDrawable *) textv_window, NULL, 
              &color, fileName); 
     gdk_window_set_back_pixmap (textv_window, pixmap, FALSE); 
     g_object_unref(pixmap); 

     textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textv)); 

     gtk_text_buffer_create_tag (textBuffer, "Red", "foreground", "Red", NULL); 
     gtk_text_buffer_create_tag (textBuffer, "RedBold","foreground", "Red",NULL); 
      gtk_text_buffer_create_tag(textBuffer, "gray_bg", "background", "gray", NULL); 
      gtk_text_buffer_create_tag(textBuffer, "italic", "style", PANGO_STYLE_ITALIC, NULL); 
      gtk_text_buffer_create_tag(textBuffer, "bold","weight", PANGO_WEIGHT_BOLD, NULL); 
     gtk_text_buffer_create_tag (textBuffer, "RedFontWeight", "weight", 1000,NULL); 
     gtk_text_buffer_create_tag (textBuffer, "RedBoldFontWeight","weight", 1000,NULL); 
     gtk_widget_show(textv); 
     gtk_widget_show(window); 
     gdk_threads_leave(); 
     return index; 
    } 

    void *fsmThread_RunFunction() 
    { 
     int pollMsgRetVal = -1; 
     printf("Now enter into for image"); 
     dispInfoPage("../images/givefp.gif",1); 
     sleep(5); 
     dispInfoPage("../images/bootup.gif",1); 
     sleep(5); 
     dispInfoPage("../images/givefp.gif",1); 
     sleep(5); 
     dispInfoPage("../images/bootup.gif",1); 
     sleep(5); 
     printf("Now enter into for disptext"); 
     dispTextPage("",0); 
     printf("Now exit for disptext"); 
    } 

    int main(int argc, char *argv[]) 
    { 
     GThread *fsmThreadId; 
     GError *error = NULL; 
     g_thread_init(NULL); 
     dispInit(argc, argv); 
     dispInfoPage("../images/bootup.gif",1); 
     sleep(5); 
     printf("Now creat ethread "); 
     fsmThreadId = g_thread_create(fsmThread_RunFunction,NULL,TRUE,&error); 
     if (error) { 
      fflush(stderr); 
      exit(1); 
     } 
     g_thread_join(fsmThreadId); 
     sleep(2); 

     printf("ENd of main"); 
     return 0; 
    } 

回答

1

所有的UI操作/功能可能只從一個線程調用。這是幾乎所有(我所知道的)UI庫(Gtk +,Qt,wxWidgets ...)的常見API使用要求。使用工作線程,使用g_idle_addg_timeout_add並在那裏進行(即時縮短)UI修改。

+0

:什麼是跨線程通信的最佳方法 – Ragav

+0

@Ragav他已經提到過它:通常情況下,您會使用來自非主線程的'g_idle_add()'。 – jku

+1

'g_idle_add'結合'g_async_queue_push/pop'(後者可能不需要,取決於你的問題以及你如何實現它) – drahnr

相關問題