IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

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+.

SommaireGTK+GtkWidget (43)
précédent sommaire suivant
 

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);

Mis à jour le 16 novembre 2006 sub_khaine

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)
Cette macro renvoie TRUE si widget est un GtkLabel.

Mis à jour le 16 novembre 2006 sub_khaine

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.

Mis à jour le 16 novembre 2006 sub_khaine

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);

Mis à jour le 16 novembre 2006 sub_khaine

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);
Mais lorsque que l'on crée une fenêtre avec plusieurs widgets, il est plus pratique de demander d'afficher tout son contenu grâce à la fonction :

Code C : Sélectionner tout
void gtk_widget_show_all (GtkWidget *widget);

Mis à jour le 16 novembre 2006 sub_khaine

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
Cela vient du fait qu'un GtkWindow hérite des GtkBin et qu'il ne peut contenir qu'un seul widget. Pour résoudre ce problème, il faut insérer vos widgets dans un GtkBox, un GtkButtonBox, un GtkPaned ou un GtkTable selon vos besoins.

Mis à jour le 16 novembre 2006 sub_khaine

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.

Mis à jour le 16 novembre 2006 sub_khaine

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.

Mis à jour le 16 novembre 2006 sub_khaine

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);
Le second paramètre est de type GtkStateType et permet de spécifier l'état du widget pour lequel on souhaite modifier la couleur :

  • 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

Mis à jour le 16 novembre 2006 sub_khaine

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.

Mis à jour le 16 novembre 2006 sub_khaine

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);
Si vous ne désirez pas changer la largeur ou la hauteur, vous pouvez mettre l'argument à la valeur -1 ce qui gardera la taille préférée par défaut.
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);
Pensez donc à toujours remonter dans la hiérarchie des widgets pour voir si la fonction que vous recherchez n'existe pas !

Mis à jour le 16 novembre 2006 P'tit Pack

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;

Mis à jour le 16 novembre 2006 P'tit Pack

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; 
}
Et voici le résultat obtenu :

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).

Mis à jour le 16 novembre 2006 sub_khaine

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; 
}

Mis à jour le 14 mai 2007 sub_khaine

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().

Mis à jour le 14 mai 2007 P'tit Pack

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()

Mis à jour le 14 mai 2007 Michel_57

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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.