我有以下代码使用GTK + widget工具包显示带按钮的窗口。单击此按钮将显示模式对话框。请注意,对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();
}
答案 0 :(得分:5)
将您的号召gtk_dialog_run
置于由g_idle_add()
调用的函数中。
答案 1 :(得分:3)
在gtk_dialog_run docs中有一个独立的提及,gtk_dialog_run
只会阻止与模态对话框相同的window group中的窗口的交互。
答案 2 :(得分:2)
对我来说,你的测试代码工作正常,我看到了两个错误:
但是,我可以点击按钮并在文件对话框中浏览文件系统,我可以使用打开/关闭按钮。
我可能会猜到你所使用的GTK版本有一个特定的错误会阻止点击对话框。在不知道bug是什么的情况下,我完全相信Kurt的想法是在空闲而不是点击的处理程序中运行对话框可以解决它。通过在点击的处理程序中添加模态抓取可能会让GTK感到困惑。只是猜测。但是,我没有在GTK 2.20.1上看到这个错误。
我在代码中注意到了几件事: