У меня есть следующий код, который использует 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();
}