FAQ GTK+Consultez toutes les FAQ
Nombre d'auteurs : 10, nombre de questions : 101, dernière mise à jour : 22 février 2018 Ajouter une question
Cette faq a été réalisée à partir des questions fréquemment posées sur les forums de www.developpez.com et de l'expérience personnelle des auteurs.
Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette faq ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture, L'équipe GTK+.
- 6.2.1. GtkAboutDialog (1)
- 6.2.2. GtkFileDialog (1)
- 6.2.3. GtkComboBox (7)
- 6.2.4. GtkStatusbar (2)
- 6.2.5. GtkTextView (5)
- 6.2.6. GtkNotebook (1)
- 6.2.7. GtkImage (3)
- 6.2.8. GtkEntry (1)
- 6.2.9. GtkTreeView (2)
- 6.2.10. GtkBuilder (2)
- 6.2.11. GtkWindow (1)
- 6.2.12. GtkDrawingArea (1)
- Comment activer/désactiver un widget ?
- Comment connaître le type réel d'un GtkWidget ?
- Quand utiliser le type GtkWidget ?
- J'ai créé un widget mais rien ne s'affiche
- Comment afficher tous les widgets d'une fenêtre en une fois ?
- Comment ajouter plusieurs widgets ?
- Comment ajouter des barres de défilement à un widget ?
- Comment savoir si un widget supporte les barres de défilement ?
- Comment modifier la couleur d'un widget ?
- Pourquoi je n'arrive pas à modifier la couleur d'un widget ?
- Comment changer la taille préférée d'un widget ?
- Comment insérer des valeurs numériques dans un GtkLabel (ou autre) ?
- Comment créer un widget transparent ?
- Comment modifier le style du texte affiché ?
- Comment faire passer le focus sur un autre widget ?
- Comment détecter un clique droit sur un widget ?
Dans certaines circonstances, il peut être nécessaire d'empêcher un utilisateur d'utiliser un widget (cliquer sur un bouton, par exemple). Pour cela, il suffit de le désactiver grâce à la fonction :
Code C : | Sélectionner tout |
void gtk_widget_set_sensitive (GtkWidget *widget, gboolean sensitive);
Chaque classe dérivant des GtkWidget définit une macro permettant de savoir si une variable appartient à cette classe, par exemple pour les GtkLabel :
Code C : | Sélectionner tout |
#define GTK_IS_LABEL(widget)
Toutes les fonctions de création de widgets retournent un GtkWidget alors que pour configurer ce dernier, il faut généralement faire un cast à l'aide des macros du type GTK_TYPE_DU_WIDGET, alors dans quel cas utiliser tel ou tel type ? Il n'existe pas de réponse type, mais généralement on utilise le type GtkWidget lors de la création du widget et de sa configuration, et ensuite, lorsque l'on doit modifier le widget dans des fonctions callback, on utilise le type réel de ce dernier pour éviter d'avoir à tester son type et de faire des casts.
Pour qu'un widget soit affiché, il faut le préciser explicitement à GTK en faisant appel à la fonction :
Code C : | Sélectionner tout |
void gtk_widget_show (GtkWidget *widget);
Pour qu'un widget apparaisse à l'écran, il faut demander son affichage à l'aide de la fonction :
Code C : | Sélectionner tout |
void gtk_widget_show (GtkWidget *widget);
Code C : | Sélectionner tout |
void gtk_widget_show_all (GtkWidget *widget);
Vous avez créé une fenêtre et essayé d'ajouter plusieurs widgets dans celle-ci mais GTK+ vous dit que c'est impossible avec un message ressemblant à :
Code : | Sélectionner tout |
1 2 3 | (gtk_box.exe:492) : Gtk-WARNING **: Attempting to add a widget with type GtkButton to a GtkWindow, but as a GtkBin subclass a GtkWindow can only contain one widget at a time; it already contains a widget of type GtkButton |
Il faut distinguer deux cas :
- Le widget implémente les barres de défilement de façon native, dans ce cas il suffit d'afficher ce widget dans un objet de type GtkScrolledWindow
- Le widget ne supporte pas les barres de défilement, il faut alors ajouter le widget à un conteneur de type GtkViewport.
Les widgets qui supportent les barres de défilement possèdent une ou deux propriétés de type GtkAdjustment (une pour la barre verticale, l'autre pour la barre horizontale). Actuellement seules trois classes en sont capables :
- GtkTextView
- GtkTreeView
- GtkLayout.
Pour modifier la couleur d'un widget, il suffit d'utiliser la fonction gtk_widget_modify_bg :
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | GdkColor color; GtkWidget *p_widget = NULL; /* Creation du widget */ color.pixel = 32; color.red = 65535; color.green = 0; color.blue = 0; gtk_widget_modify_bg (p_widget, GTK_STATE_NORMAL, &color); |
- GTK_STATE_NORMAL : état de base
- GTK_STATE_ACTIVE : lorsque le widget est actif (qu'il a le focus)
- GTK_STATE_PRELIGHT : lorsque le curseur de la souris est sur le widget
- GTK_STATE_SELECTED : lorsque le widget est sélectionné (la colonne d'une liste, par exemple)
- GTK_STATE_INSENSITIVE : lorsque le widget est inactif
Le code ci-dessus fonctionne très bien, si vous n'arrivez pas à modifier la couleur d'un widget, c'est qu'il n'est pas possible de le faire directement.
C'est le cas pour les widgets qui ne sont pas des fenêtres (le flag GTK_NO_WINDOW est sélectionné, les GtkLabel par exemple), dans ce cas il faut modifier la couleur de son parent.
Si vous ne souhaitez pas modifier l'apparence de tous les enfants de ce dernier, vous pouvez isoler un widget en le plaçant dans un GtkEventBox dont vous modifiez la couleur.
Si le problème persiste, il peut s'agir du thème utilisé par GTK+ qui ne supporte pas le changement de couleur.
Tout widget héritant d'un GtkWidget, on peut utiliser la fonction :
Code C : | Sélectionner tout |
void gtk_widget_set_size_request (GtkWidget *widget, gint width, gint height);
Certains widgets implémentent leur propre fonction comme GtkWindow avec la fonction :
Code C : | Sélectionner tout |
void gtk_window_set_default_size (GtkWindow *window, gint width, gint height);
Il faut convertir la valeur numérique en chaîne puis la faire afficher par le widget :
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <gtk/gtk.h> #include <glib/gprintf.h> gint val = 10; gchar *chaine = NULL; GtkWidget *p_label = NULL; p_label = gtk_label_new (NULL); chaine = g_strdup_printf ("%d", val); gtk_label_set_text (GTK_LABEL (p_label), chaine); g_free (chaine), chaine = NULL; |
Pour commencer, il faut créer un canal alpha pour la fenêtre où le widget sera affiché, ensuite vous pouvez utiliser les fonctions de cairo pour dessiner avec un canal alpha (la fonction cairo_set_source_rgba permet de sélectionner la couleur avec un niveau de transparence).
Voici un exemple qui affiche une fenêtre transparente avec un cercle rouge semi-transparent :
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include <gtk/gtk.h> #include <gdk/gdkscreen.h> #include <cairo.h> /* * This program shows you how to create semi-transparent windows, * without any of the historical screenshot hacks. It requires * a modern system, with a compositing manager. I use xcompmgr * and the nvidia drivers with RenderAccel, and it works well. * * I'll take you through each step as we go. Minimal GTK+ knowledge is * assumed. */ /* Only some X servers support alpha channels. Always have a fallback */ gboolean supports_alpha = FALSE; static void screen_changed (GtkWidget *widget, GdkScreen *old_screen, gpointer userdata) { /* To check if the display supports alpha channels, get the colormap */ GdkScreen *screen = NULL; GdkColormap *colormap = NULL; screen = gtk_widget_get_screen (widget); colormap = gdk_screen_get_rgba_colormap (screen); if (colormap == NULL) { g_message ("Your screen does not support alpha channels!\n"); colormap = gdk_screen_get_rgb_colormap(screen); supports_alpha = FALSE; } else { g_message ("Your screen supports alpha channels!\n"); supports_alpha = TRUE; } /* Now we have a colormap appropriate for the screen, use it */ gtk_widget_set_colormap (widget, colormap); } /* This is called when we need to draw the windows contents */ static gboolean expose (GtkWidget *widget, GdkEventExpose *event, gpointer userdata) { gint width; gint height; cairo_t *cr = NULL; cr = gdk_cairo_create(widget->window); if (supports_alpha) { /* transparent */ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); } else { /* opaque white */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); } /* draw the background */ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); /* draw a circle */ gtk_window_get_size (GTK_WINDOW (widget), &width, &height); cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6); cairo_arc (cr, width / 2, height / 2, (width < height ? width : height) / 2 - 8 , 0, 2 * 3.14); cairo_fill (cr); cairo_stroke (cr); cairo_destroy (cr); return FALSE; } int main (int argc, char **argv) { GtkWidget *window = NULL; /* boilerplate initialization code */ gtk_init(&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW(window), "Alpha Demo"); g_signal_connect (G_OBJECT(window), "delete-event", gtk_main_quit, NULL); /* Tell GTK+ that we want to draw the windows background ourself. * If we don't do this then GTK+ will clear the window to the * opaque theme default color, which isn't what we want. */ gtk_widget_set_app_paintable (window, TRUE); /* We need to handle two events ourself: "expose-event" and "screen-changed". * * The X server sends us an expose event when the window becomes * visible on screen. It means we need to draw the contents. On a * composited desktop expose is normally only sent when the window * is put on the screen. On a non-composited desktop it can be * sent whenever the window is uncovered by another. * * The screen-changed event means the display to which we are * drawing changed. GTK+ supports migration of running * applications between X servers, which might not support the * same features, so we need to check each time. */ g_signal_connect (G_OBJECT (window), "expose-event", G_CALLBACK (expose), NULL); g_signal_connect (G_OBJECT (window), "screen-changed", G_CALLBACK (screen_changed), NULL); /* initialize for the current display */ screen_changed (window, NULL, NULL); /* Run the program */ gtk_widget_show_all (window); gtk_main(); return 0; } |
Pour obtenir un effet de transparence, il faut que votre système le supporte. La copie d'écran ci-dessus a été prise sous Debian Etch avec le gestionnaire de fenêtre Beryl ( Installer beryl sous XFCE4). |
C'est la bibliothèque Pango qui s'occupe d'afficher du texte, il faut donc utiliser cette API. Voici un exemple qui modifie le style d'un texte affiché par un GtkEntry :
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <gtk/gtk.h> int main (int argc, char **argv) { gtk_init (&argc, &argv); { GtkWidget *p_window = NULL; p_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (p_window), "delete-event", G_CALLBACK (gtk_main_quit), NULL); { GtkWidget *p_entry = NULL; p_entry = gtk_entry_new (); { PangoFontDescription *desc = pango_font_description_new (); pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD); gtk_widget_modify_font (p_entry, desc); } gtk_container_add (GTK_CONTAINER (p_window), p_entry); } gtk_widget_show_all (p_window); } gtk_main (); return 0; } |
Il faut utiliser la fonction gtk_widget_grab_focus et lui passer le GtkWidget qui doit recevoir le focus. Il faut cependant vérifier si le widget cible peut prendre le focus, ce qu'on peut déterminer facilement avec la fonction gtk_widget_get_can_focus().
Pour détecter un clic droit sur un widget, il suffit d'intercepter le signal button-press-event puis de tester la valeur de l'attribut gtk.gdk.Event.button :
Code python : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import gtk class UneClasse: def __init__(self): self.fenetre=gtk.Window(gtk.WINDOW_TOPLEVEL) self.fenetre.set_title("Titre") self.fenetre.set_default_size(200,200) self.fenetre.set_position(gtk.WIN_POS_CENTER) self.fenetre.connect("destroy",gtk.main_quit,None) self.bouton=gtk.Button("cliquez pour voir") self.bouton.connect("button-press-event",self.unClick) self.fenetre.add(self.bouton) self.fenetre.show_all() gtk.main() def unClick(self,w,event): if (event.button==3): self.bouton.set_label("droit") elif (event.button==1): self.bouton.set_label("gauche") if __name__ == '__main__': UneClasse() |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.