这是一个程序,其中有两个按钮(连接和断开连接)。点击' connect'按钮,它调用' button1_clicked_do_job()'具有一定条件的功能。另一方面'断开'按钮用于改变while的条件。问题是断开连接按钮不起作用。如何连接'回调函数没有返回到main()?
以下是代码:
#include<gtk/gtk.h>
static int check=1;
void button2_clicked_disconnect(GtkWidget *widget, gpointer data2)
{
check=0; //Change the condition of while
}
void button1_clicked_do_job(GtkWidget *widget, gpointer data1)
{
do{
g_print("Accept Connection\n");
sleep(2);
} while(check==1);
g_print("Reject Connection\n");
}
int main( int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *fixed;
GtkWidget *button1;
GtkWidget *button2;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 250, 150);
gtk_window_set_title(GTK_WINDOW(window), "Connect_N__Disconnect");
fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), fixed);
button1 = gtk_button_new_with_label("Connect");
gtk_widget_set_size_request(button1, 80, 30);
gtk_fixed_put(GTK_FIXED(fixed), button1, 30, 50);
button2 = gtk_button_new_with_label("Disconnect");
gtk_widget_set_size_request(button2, 80, 30);
gtk_fixed_put(GTK_FIXED(fixed), button2, 130, 50);
g_signal_connect(G_OBJECT(button1), "clicked",
G_CALLBACK(button1_clicked_do_job), NULL);
g_signal_connect(G_OBJECT(button2), "clicked",
G_CALLBACK(button2_clicked_disconnect), NULL);
g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
答案 0 :(得分:1)
一般来说,你不应该在主线程中运行阻塞代码(比如长时间运行的while循环),因为它会使应用程序无响应 - 所有函数最好都应该以毫秒为单位返回。在你的情况下,你也期望主循环调用你的其他事件处理程序,但永远不会给主循环一个机会:while循环只是永远执行。换句话说:第一个处理程序需要在主循环可以调用第二个处理程序之前返回。
如何解决这个问题取决于你的实际问题:使用异步代码或空闲处理程序应该是第一个选项,而工作线程是另一个选项(但是当你知道实际需要它时,请只添加线程)。也可以手动“泵”事件循环,但这应该是最后一个选项。有关详细信息,请参阅main loop reference。
你的例子看起来像这样:
gboolean check_connection (gpointer user_data)
{
/* g_print what you want based on check value */
if (check == 0)
return FALSE;
return TRUE;
}
void button1_clicked_do_job(GtkWidget *widget, gpointer data1)
{
g_timeout_add_seconds (2, check_connection, NULL);
}