J'ai le code suivant qui utilise GTK + widget toolkit pour afficher une fenêtre avec un bouton. Cliquez sur ce bouton pour afficher une boîte de dialogue modale. Notez que l'appel à gtk_dialog_run
commencera récursivement une autre instance de la boucle principale, c'est-à-dire que la fonction on_click
ne retournera pas jusqu'à ce que la boîte de dialogue soit fermée.Comment créer des boîtes de dialogue modales multiples mais indépendantes dans GTK +?
Je voudrais avoir deux de ces fenêtres de haut niveau, chacune avec un bouton et la capacité de générer leur propre dialogue modal. L'affichage de la boîte de dialogue ne ferait que désactiver la fenêtre qui l'a engendrée et il pourrait y avoir jusqu'à deux boîtes de dialogue modales actives en même temps, une pour chaque fenêtre de niveau supérieur.
Dans Win32, je pourrais accomplir cela simplement en exécutant chaque fenêtre de niveau supérieur dans un thread séparé. Cependant, il semble que gtk_main
ne peut être exécuté qu'à partir d'un thread. Alors, comment puis-je gérer plusieurs piles de fenêtres dans GTK + (sans sacrifier la simplicité de gtk_dialog_run
si possible)?
Mise à jour: Le code affiche maintenant les deux fenêtres et les ajoute à leurs groupes de fenêtres respectifs.
#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();
}
Merci d'avoir répondu.J'ai essayé de placer chaque fenêtre dans son propre groupe, mais après avoir cliqué sur le bouton dans l'une des fenêtres, l'autre fenêtre n'accepte toujours pas les clics (bien qu'elle réponde de manière surprenante aux mouvements de la souris). Même si cela a fonctionné correctement, je ne peux toujours pas imaginer comment cela pourrait fonctionner sans utiliser plusieurs threads. Si je clique sur le bouton 1, puis sur le bouton 2 puis cache le dialogue 1, si les boucles sont exécutées dans le même thread, le 'gtk_dialog_run' pour le premier dialogue ne peut pas retourner jusqu'à ce que le dialogue 2 soit également fermé. Je pense qu'il y a un point fondamental qui me manque. – avakar
Etes-vous sûr d'avoir ajouté les boîtes de dialogue aux groupes de fenêtres? – Tobu
Bonne prise. Malheureusement, rien n'a changé après que je l'ai réparé. J'ai mis à jour la question avec mon code actuel si vous pouviez l'examiner. Dans les deux cas, vous avez mon +1. – avakar