繁体   English   中英

GDK线程不允许gtk更改(制作计时器)

[英]GDK Threads not allowing gtk changes(Making timer)

 #include <gtk/gtk.h>
 #include<string.h>
 #include<stdio.h>
 #include <stdbool.h>
 #include<stdlib.h>

 static GtkWidget *textlabel_question_no;
 static GtkWidget *textlabel_answer1;
 static GtkWidget *textlabel_answer2;
 static GtkWidget *textlabel_answer3;
 static GtkWidget *textlabel_answer4;
 static GtkWidget *textlabel_question;
 static GtkWidget *textlabel_timer;
 static GtkWidget *textlabel_timeleft;
 static GtkWidget *button_next;
 static GtkWidget *window2;
 static GtkWidget *window31;
 static GThread  *thread;

 void show_info(GtkWidget *window2);

 // thread for timer
 static gpointer thread_Func(gpointer data)
 {

  // gdk_threads_enter();
int min=0,sec;//min=29

while(min > -1 )
{
    sec = 10;
    while(sec>=0)
    {
       sleep(1);
      char* timer_text=malloc(sizeof(char)*40);
      if(sec>9)
      {
        sprintf(timer_text,"%d : %d",min,sec);
      }
      else
      {
        sprintf(timer_text,"%d : 0%d",min,sec);
      }
      gtk_label_set_text(GTK_LABEL(textlabel_timer),timer_text);
      sec--;
    }
    min--;
    }
   // gdk_threads_leave();

    // gdk_threads_enter();
      g_printf("in show_info\n");
      GtkWidget *dialog;
      dialog = gtk_message_dialog_new(GTK_WINDOW(window2),
                     GTK_DIALOG_DESTROY_WITH_PARENT,
                     GTK_MESSAGE_INFO,
                     GTK_BUTTONS_OK,
             "Your Time is UP !!!\n Lets see the Result & Statistics...","title");                         
         gtk_window_set_title(GTK_WINDOW(dialog), "Time Finished");
         gint result=gtk_dialog_run(GTK_DIALOG(dialog));

         switch(result)
            {
              case GTK_RESPONSE_OK:
              gtk_widget_hide(window2);
             g_printf("in show_info\n");

            system("./result &");
            //gtk_main_quit();
            break;
           }
          //sleep(10);
       gtk_widget_destroy(dialog);


     /*
     window31 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     gtk_window_set_position(GTK_WINDOW(window31), GTK_WIN_POS_CENTER);
     gtk_window_set_title(GTK_WINDOW(window31), "Examination Panel");
     gtk_container_set_border_width(GTK_CONTAINER(window31),12);
     gtk_window_set_resizable(GTK_WINDOW(window31),FALSE);
     gtk_widget_set_size_request(window31,300,150);
     gtk_widget_show_all(window31);
     //sleep(10);
      gdk_threads_leave();*/
     return NULL;
   }

    static void next_question_label_change(GtkWidget *button_next,gpointer data)
     { 
     g_printf("in button_next\n");
     static int question_value=2;
     char *question_label = malloc(sizeof(char)*50);
     sprintf(question_label,"Question %d of 10.",question_value);
     gtk_label_set_text(GTK_LABEL(textlabel_question_no),question_label);
     if(question_value<10)
       question_value++;
   }



     //For Submit button dialog box
     static void test_submit_window(GtkWidget *button_next,GtkWidget *window2)
     {
       GtkWidget *dialog;
       dialog = gtk_message_dialog_new(GTK_WINDOW(window2),
                 GTK_DIALOG_DESTROY_WITH_PARENT,
                 GTK_MESSAGE_QUESTION,
                 GTK_BUTTONS_YES_NO,
                 "Are you sure to Submit the Test?");

     gtk_window_set_title(GTK_WINDOW(dialog), "Submit Test Confirmation");
     gint result = gtk_dialog_run (GTK_DIALOG (dialog));


     switch(result)
      {
      case GTK_RESPONSE_YES:

      system("./result &");
      gtk_widget_hide(window2);
            break;
      case GTK_RESPONSE_NO:
      break;
      }
     gtk_widget_destroy(dialog);

   }

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

     GTimer *g_time;

     GtkWidget *fixed;
     GtkWidget *radio1,*radio2,*radio3,*radio4;
     GtkWidget *button_submit;
     GtkWidget *textlabel_title;
     GtkWidget *image;
     GtkWidget *image2;
     GError *error = NULL;
     GdkPixbuf *pixbuf;  
     GtkWidget *scrolled_window;


     /* Secure glib */
      if( ! g_thread_supported() )
    g_thread_init( NULL );

     //g_threads_init(NULL);
      //g_thread_init(NULL);
      /* Secure gtk */
      gdk_threads_init();

      /* Obtain gtk's global lock */



    // intialiazation
     gtk_init (&argc, &argv);




     //window attributes position,size,title
     window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     gtk_window_set_position(GTK_WINDOW(window2), GTK_WIN_POS_CENTER);
     gtk_window_set_title(GTK_WINDOW(window2), "Examination Panel");
     gtk_container_set_border_width(GTK_CONTAINER(window2),12);
     gtk_window_set_resizable(GTK_WINDOW(window2),FALSE);
     gtk_widget_set_size_request(window2,800,450);

     button_next = gtk_button_new_with_label("Next>>");
     button_submit = gtk_button_new_with_label("Submit");

     textlabel_title = gtk_label_new("-> TECHNICAL EXAM <-");
     textlabel_question = gtk_label_new("question placed here");
     textlabel_question_no = gtk_label_new(" Question 1 of 10.");
     textlabel_answer1 = gtk_label_new(" answer 1");
     textlabel_answer2 = gtk_label_new(" answer 2");
     textlabel_answer3 = gtk_label_new(" answer 3");
     textlabel_answer4 = gtk_label_new(" answer 4");
     textlabel_timer =   gtk_label_new("30:00");
     textlabel_timeleft = gtk_label_new("Time Left  :");



     //radio button for option
    radio1 =  gtk_radio_button_new_with_label (NULL , "A. ");
    radio2 =  gtk_radio_button_new_with_label_from_widget
            (GTK_RADIO_BUTTON(radio1),"B.");                         
     radio3 = gtk_radio_button_new_with_label_from_widget
             (GTK_RADIO_BUTTON (radio1),"C. ");
     radio4 = gtk_radio_button_new_with_label_from_widget
              (GTK_RADIO_BUTTON (radio1),"D. ");


  // For image
     pixbuf = gdk_pixbuf_new_from_file_at_size 
             ("/home/trilok/trantorlogo.png", 100,  100, &error);
   if(!pixbuf)
    {
   g_print ("Error: %s\n",error->message);
    g_error_free (error);
  /* Handle error here */
  }
  image = gtk_image_new_from_pixbuf(pixbuf);
  image2 = gtk_image_new_from_pixbuf(pixbuf);
  g_object_unref (pixbuf);




 //For Signals
 g_signal_connect (window2, "destroy", G_CALLBACK (gtk_main_quit), NULL);
 g_signal_connect (button_next,"clicked",G_CALLBACK
            (next_question_label_change), NULL);
 g_signal_connect (button_submit,"clicked",G_CALLBACK(test_submit_window),window2);


 //timer

 // pthread_create(&pth,NULL,threadFunc,"foo");
 /* Create new thread */
  thread = g_thread_create( thread_Func,NULL,
                          FALSE,&error);
  if( ! thread )
  {
    g_print( "Error: %s\n", error->message );
    return( -1 );
  }


  // For scrolled window 
  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_set_border_width (GTK_CONTAINER (scrolled_window),10);
   gtk_scrolled_window_set_policy 
         (GTK_SCROLLED_WINDOW     
           (scrolled_window)
        ,GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);


   //fixed
   fixed = gtk_fixed_new();
   gtk_container_add(GTK_CONTAINER(window2), fixed);
  gtk_widget_show(fixed);
  gtk_scrolled_window_add_with_viewport
             (GTK_SCROLLED_WINDOW(scrolled_window),textlabel_question);
  gtk_widget_set_size_request(scrolled_window,580,150);


 //scrolled border
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
                   GTK_SHADOW_IN);
  gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolled_window),
                 GTK_CORNER_TOP_LEFT);




  gtk_fixed_put(GTK_FIXED(fixed), scrolled_window, 70, 110);
  gtk_fixed_put(GTK_FIXED(fixed), image, 0, 0);
  gtk_fixed_put(GTK_FIXED(fixed), image2, 0, 510);
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_title, 300, 20);
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_timeleft, 610, 70);  
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_timer, 690, 70);  
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_question_no, 65, 70);  
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_answer1,170, 300);
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_answer2,170, 350);
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_answer3,170, 400);
  gtk_fixed_put(GTK_FIXED(fixed), textlabel_answer4,170, 450);
  gtk_fixed_put(GTK_FIXED(fixed), radio1, 100,300);
  gtk_fixed_put(GTK_FIXED(fixed), radio2, 100,350);
  gtk_fixed_put(GTK_FIXED(fixed), radio3, 100,400);
  gtk_fixed_put(GTK_FIXED(fixed), radio4, 100,450);
  gtk_fixed_put(GTK_FIXED(fixed), button_next,620, 500);
  gtk_fixed_put(GTK_FIXED(fixed), button_submit,690, 500);
  gtk_widget_show_all(window2);


   //gdk_threads_enter();
   GDK_THREADS_ENTER();
    gtk_main();

   /* Release gtk's global lock */
   //gdk_threads_leave();
    GDK_THREADS_LEAVE();

 return 0;
 }

实际上,我在考试模拟器上做一个计时器。 我的计时器正常工作,但是问题是,当计时器转到0:00时我必须打开一个对话框。 她,我已经实现了线程以使计时器。 问题是当计时器转到0:00时,我出现了细分错误。 gdk线程不允许调用gtk小部件。

我在这里先向您的帮助表示感谢。 一些纠正上面的代码使它发生将不胜感激

  1. 目前尚不清楚是否使用gdk_threads_enter() ,因为有很多注释掉的调用和一个宏。 GTK +不是线程安全的,您尝试的方法不是正确的方法。
  2. 您确实不需要为此使用线程,只需使用glib计时器即可。
  3. 您正在从timer_text分配中泄漏内存; gtk_label_set_text()不会转移文本缓冲区的所有权(请注意,它是const )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM