繁体   English   中英

如何在GTK +中创建多个但独立的模态对话框?

[英]How do I create multiple but independent modal dialogs in GTK+?

我有以下代码使用GTK +小部件工具包显示带按钮的窗口。 单击此按钮将显示模式对话框。 请注意,对gtk_dialog_run的调用将递归地启动主循环的另一个实例,即on_click函数将不会返回,直到对话框被解除。

我想有两个这样的顶级窗口,每个窗口都有一个按钮,能够生成自己的模态对话框。 显示对话框只会禁用产生它的窗口,同时最多可以有两个活动模式对话框,每个顶级窗口一个。

在win32中,我可以通过在单独的线程中运行每个顶级窗口来完成此操作。 但是,似乎gtk_main只能从一个线程运行。 那么如何在GTK +中管理多个窗口堆栈(如果可能的话,不会牺牲gtk_dialog_run的简单性)?

更新:代码现在显示两个窗口并将它们添加到各自的窗口组。

#include <gtk/gtk.h>

struct modal_stack
{
    GtkWindowGroup * group;
    GtkWidget * window;
};

static void on_click(GtkWidget *widget, gpointer sptr)
{
    modal_stack * s = (modal_stack *)sptr;
    GtkWidget * dialog = gtk_file_chooser_dialog_new(
        "Open File", 0, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
        GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(s->window));
    gtk_window_group_add_window(s->group, GTK_WINDOW(dialog));
    gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_window_group_remove_window(s->group, GTK_WINDOW(dialog));
    gtk_widget_destroy(dialog);
}

void create_window(modal_stack & s)
{
    s.group = gtk_window_group_new();
    s.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_widget_set_usize(s.window, 200, 200);
    g_signal_connect(G_OBJECT (s.window), "destroy",
        G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(G_OBJECT (s.window), "delete_event",
        G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget * button = gtk_button_new ();
    gtk_button_set_label(GTK_BUTTON(button), "show dialog");
    g_signal_connect(G_OBJECT (button), "clicked",
        G_CALLBACK(on_click), (gpointer) &s);
    gtk_widget_show(button);

    gtk_container_add(GTK_CONTAINER (s.window), button);
    gtk_widget_show(s.window);

    gtk_window_group_add_window(s.group, GTK_WINDOW(s.window));
}

int main(int argc, char *argv[])
{
    gtk_init (&argc, &argv);
    modal_stack wnd1, wnd2;
    create_window(wnd1);
    create_window(wnd2);
    gtk_main();
}

将您对gtk_dialog_run的调用放在由g_idle_add()调用的函数中。

gtk_dialog_run文档中有一个不连续的提及, gtk_dialog_run将只阻止与模式对话框在同一窗口组中的窗口的交互。

对我来说,你的测试代码工作正常,我看到两个错误:

  • 你注意到gtk_dialog_run()是嵌套的,所以外面的东西正在内部等待。 除了在这种情况下避免使用gtk_dialog_run()之外,这不是真正可以解决的问题。
  • 有一个关于GTK_IS_WINDOW_GROUP的警告,我认为手动添加/删除窗口组中的对话框正在破坏引用计数

但是,我可以点击按钮并在文件对话框中浏览文件系统,我可以使用打开/关闭按钮。

我猜可能会有一个特定于您正在使用的GTK版本的错误,这会阻止单击对话框。 在不知道bug是什么的情况下,我完全相信Kurt的想法是在空闲而不是点击的处理程序中运行对话框可以解决它。 通过在点击的处理程序中添加模态抓取可能会让GTK感到困惑。 只是猜测。 但是,我没有在GTK 2.20.1上看到这里的错误。

我在代码中注意到的一些事情:

  • gtk_widget_set_usize可能应该是gtk_window_set_default_size
  • 您无需手动将对话框添加/删除到窗口组。 set_transient_for自动将对话框添加到父窗口组,并且销毁窗口会自动将其从窗口组中删除。 删除这些调用修复了我在对话框取消时看到的警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM