GTK Main blocking Others threads.How 解决

GTK Main blocking Others threads.How to solve

我有 2 个线程

1)持有GTK主界面和gtk屏幕显示代码(代码解释如下) 2)根据用户需求生成按键事件

if() 阻止我移植到我的代码中。但结果是一样的。一旦信号生成。之后它不会进入第二个线程(信号生成线程)。已放置调试打印,但它没有发生似乎它在第一个线程上等待 gtk_main。

我的代码是什么:

void S1(void)
{
 GtkWidget *Win_1;
 GtkBuilder *builder;        
 builder = gtk_builder_new ();
 gtk_builder_add_from_file (builder, "/home/glade/glade1.glade", NULL);
 window = GTK_WIDGET (gtk_builder_get_object (builder, "Win_1"));        
 g_signal_connect_swapped(G_OBJECT(window), "destroy",   G_CALLBACK(gtk_main_quit), G_OBJECT(window));
 g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK(kp_event), NULL);
 gtk_widget_show_all(window);
 gtk_main(); 

}

kp_event()
{
    gtk_widget_destroy (window);            
    S2();
}

S2 与 S1 相同,只有屏幕项 difference.Am 从 S1 的按键处理程序调用 S2(),反之亦然。由于我没有连接键盘,需要根据用户通过套接字或其他方式输入的内容更改两个屏幕。

您可能只需要调用一次 gtk_main(),并使用 gtk_widget_hide()gtk_window_present(),而不是 gtk_widget_destroy(),将 window1 和 window2 声明为全局变量,并在启动时创建两个 windows。示例代码:

GtkWidget * window1;
GtkWidget * window2;

void S1() {
  // create the window

  window1 = GTK_WIDGET (gtk_builder_get_object (builder, "Win_1"));  

  // do not call gtk_main()
}

void S2() {
  // create the window

  window2 = GTK_WIDGET (gtk_builder_get_object (builder, "Win_2"));  

  // do not call gtk_main()
}

kp_event_S1() {
    gtk_widget_hide(window1);
    gtk_window_present(GTK_WINDOW(window2));            
}

kp_event_S2() {
    gtk_widget_hide(window2);
    gtk_window_present(GTK_WINDOW(window1));            
}

int main() {
  gtk_init();

  S1();
  S2();
  gtk_widget_hide(window2);
  gtk_main();
}

如果不想使用全局变量,可以这样做:

GtkWidget * S1() {
  // create the window

  GtkWidget * window1 = GTK_WIDGET (gtk_builder_get_object (builder, "Win_1"));  

  return window1;
}

GtkWidget * S2() {
  // create the window

  GtkWidget * window2 = GTK_WIDGET (gtk_builder_get_object (builder, "Win_2"));  

  return window2;
}

gboolean kp_event_S1(GtkWidget * window, GdkEvent e, gpointer user_data) {
  gtk_widget_hide(window);
  gtk_window_present(GTK_WINDOW(user_data));            
}

gboolean kp_event_S2(GtkWidget * window, GdkEvent e, gpointer user_data) {
  gtk_widget_hide(window);
  gtk_window_present(GTK_WINDOW(user_data));            
}

int main() {
  gtk_init();

  GtkWidget * w1 = S1();
  GtkWidget * w2 = S2();
  gtk_widget_hide(w2);

  g_signal_connect (G_OBJECT (w1), "key-press-event", G_CALLBACK(kp_event_S1), (gpointer)w2);
  g_signal_connect (G_OBJECT (w2), "key-press-event", G_CALLBACK(kp_event_S2), (gpointer)w1);
  gtk_main();
}