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();
}
我有 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();
}