gtk2.0在计算密集代码前创建窗体无法正常显示的问题

⌚Time: 2025-05-17 20:20:00

👨‍💻Author: Jack Ge

我有一个计算密集的代码,占用长时间资源阻塞程序运行,想要在之前加一个无任何控件的窗体,提示用户不要做任何操作。就是这样

// 创建无边框窗口作为对话框
    GtkWidget *dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_decorated(GTK_WINDOW(dialog), FALSE); // 无标题栏
    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);//设置模态窗口,防止用户对其它窗体操作
    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(dialog), 200, 80);
    
    // 添加内容
    GtkWidget *vbox = gtk_vbox_new(FALSE, 5);
    GtkWidget *label = gtk_label_new("parsing,do not do any operation");
    gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
    gtk_container_add(GTK_CONTAINER(dialog), vbox);
    gtk_widget_show_all(dialog);
    
    //运行计算代码
    do_function();
    
    //销毁提示窗口
    gtk_widget_destroy(dialog);
    

但是结果就是,创建的窗体不能显示。是黑框。我知道是因为计算代码阻塞了窗体绘制的进行。这是AI的回答:

GTK2.0使用单线程事件循环模型:所有 GTK 操作(包括定时器、绘图、事件处理等)都在主线程中执行,当执行阻塞操作(如长时间计算、同步 I/O 等)时,会阻止事件循环处理其他事件,这会导致界面"冻结",定时器无法触发,用户界面无响应。

解决办法也简单,就是在阻塞代码之前强制绘制GUI事件:

    ...
    // 强制处理所有挂起的GUI事件,后面是计算密集操作,会造成GTK的主循环没有机会处理绘图事件
    while (gtk_events_pending()) {
        gtk_main_iteration();
    }

    //运行计算代码
    do_function();

    //销毁提示窗口
    gtk_widget_destroy(dialog);

这样就可以正常显示提示窗口,并且在执行计算结束后自动销毁。

弹出的提示窗体