0

gtk4 删除了以下的阻塞行为GtkDialogsint res = gtk_dialog_run(GTK_DIALOG(dialog));

建议的替代方法是使对话框模态并连接"response"信号。但这有一个很大的缺点:一些旧代码库具有线性和确定性的 CFG。仅更改调用和处理所有对话框的方式会导致这样一个事实,即如果在外部范围中预期对话的处理,则离开范围后代码可能是错误的。

为了避免这种情况,我使用了std::promisestd::future但这会阻止 gtk-event 循环:/。

我提出的解决方案是,“加入” gtk-event-loop,直到结果准备好。这将具有两种方法的优点:“不要停止世界”/处理事件循环保持线性 CFG。但它有一个缺点,即在递归调用连接时可能导致堆栈溢出或饥饿。

建议/搜索解决方案的伪代码:

auto future_result = generate_future_for_dialog_result(dialog);
while(!future_result.isDone()){
    g_join();
}

我的第一个不工作的方法:

    auto wait_for_gtk_dialog_result =
            [](GtkDialog* dialog) {
                std::promise<int> promise;
                auto future = promise.get_future();
                g_signal_connect(dialog, "result",
                                 GCallback(+[](GtkDialog* /*self*/, int result, std::promise<int>* promise) {
                                     promise->set_value(result);
                                 }),
                                 &promise);
                return future.get();
            };

有加入事件循环的功能吗?
如果不; 有没有实现类似的好选择?

编辑:在文档中找到了一种有前途的方法:查看g_main_context_iteration.

    auto wait_for_gtk_dialog_result =
            [](GtkDialog* dialog) {
                std::promise<int> promise;
                auto future = promise.get_future();
                g_signal_connect(dialog, "result",
                                 GCallback(+[](GtkDialog* /*self*/, int result, std::promise<int>* promise) {
                                     promise->set_value(result);
                                 }),
                                 &promise);
                do {
                    g_main_context_iteration(g_main_context_default(), false);
                } while (future.wait_for(std::chrono::milliseconds(1)) != std::future_status::ready);
                return future.get();
            };
4

0 回答 0