c - 如何从一个按钮发送信号,而其他按钮的回调函数没有将信号返回到 GTK+ 中的 main()

标签 c gtk gtk3

这是一个程序,其中有两个按钮(连接断开)。单击“连接”按钮时,它会调用“button1_clicked_do_job()”函数,同时满足某些条件。另一方面,“断开连接”按钮用于更改 while 的条件。问题是“断开连接”按钮不起作用。当“connect”回调函数没有返回到 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;
}

最佳答案

一般来说,您不应在主线程中运行阻塞代码(例如长时间运行的 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);
}

关于c - 如何从一个按钮发送信号,而其他按钮的回调函数没有将信号返回到 GTK+ 中的 main(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23075862/

相关文章:

image - 带有图像 GTK 的组合框

c++ - 如何删除 gtkmm 中自定义 TreeModel 中的 user_data?

gtk3 - 包裹的 GtkLabel 巨大的高度

c - scanf 出了问题

c - 如何使用 Metropolis-Hastings 算法将 C 或 C++ 代码合并到我的 R 代码中以加速 MCMC 程序

c - 包装 GTK+ 函数

python - 在 Python GTK3 中收听 Control + 鼠标滚轮滚动事件

c - 为什么 Ken Thompson 在 "Reflections on Trusting Trust"中提到的 C quine 不起作用?

python - 无法在嵌入 Python 的多线程 C 应用程序中终止多处理池

c++ - 如何 "disconnect"加速器、按键事件或鼠标按下事件在 GTK+ 小部件中?