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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

Comment avoir un GtkGrid ressemblant à un tableur ?


Sujet :

GTK+ avec C & C++

  1. #1
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut Comment avoir un GtkGrid ressemblant à un tableur ?
    Bonjour à toutes et à tous.

    Bon nombre d'entre-vous pose souvent cette question. Je voudrais avoir une table avec chaque case entourée, comme dans un tableur. Ayant un peu de temps devant moi je me suis mis à la tâche pour essayer de vous donner une solution élégante à ce "douloureux problème" .

    Tout d'abord il est bon de préciser que la solution que je vais vous donner ne fonctionne que pour Gtk+ v3.0 et ultérieures. En effet elle utilise cairo. Ceci étant dit, passons aux choses sérieuses.

    Ce qu'il faut comprendre aujourd'hui avec Gtk+v3.0 est que tout widget utilise cairo pour "se dessiner". Nous allons utiliser simplement cette propriété pour ajouter notre petite touche personnelle.

    Pour l'exemple j'ai donc créé une fenêtre principale dans laquelle j'insère un GtkGrid. Jusqu'ici rien de bien nouveau. Ensuite à l'aide de deux boucles imbriquées j'insère dans le GtkGrid 9 GtkLabel initialisés avec les coordonnées de chacun d'eux histoire d'avoir un affichage clair. Tout le monde arrive à faire ce genre de chose sans trop de problème. Mais comment maintenant ajouter un cadre autour de chaque case ?

    La solution est finalement simple. Puisqu'un widget utilise cairo il déclenche donc le signal "draw". Certains d'entre-vous utilise ce signal de manière courante avec les GtkDrawingArea pour pouvoir dessiner. Nous allons en faire de même pour chaque GtkLabel.
    J'assigne un callback pour chaque widget enfant inséré dans le GtkGrid attaché au signal "draw". Dans ce callback je récupère naturellement le contexte graphique (cairo_t) avec lequel je peux dessiner directement sur le widget.

    Dans le code exemple çi-dessous j'ai volontairement agrémenté un peu le code. Chaque case est entourée par un trait discontinue de couleur différente histoire que chacun puisse voir comment on peut modifier à son gré l'apparence finale du widget.

    J'arrête là le charabia et vous livre le code en pâture. À vos commentaires...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
    /*
     * main.c
     * Copyright (C) 2013 Gerald Dumas <gerald.dumas@laposte.net>
     *
     * tableur is free software: you can redistribute it and/or modify it
     * under the terms of the GNU General Public License as published by the
     * Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     * 
     * tableur is distributed in the hope that it will be useful, but
     * WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     * See the GNU General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License along
     * with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
     
    #include <config.h>
    #include <gtk/gtk.h>
     
    gboolean draw_child_widget (GtkWidget *ChildWidget, cairo_t *cr, GdkRGBA *color)
    {
    	/* Dans cette fonction nous accédons au context cairo de chaque widget enfant inséré dans le GtkGrid.
    	 * Il nous suffit maintenant de dessiner ce que l'on veut dessus.
    	 * La couleur de chaque encadrement est récupérée dans le pointeur utilisateur.
    	 */
    	gdouble dash[2];
    	gint width = gtk_widget_get_allocated_width (ChildWidget);
    	gint height = gtk_widget_get_allocated_height (ChildWidget);
     
    	dash[0]=5;
    	dash[1]=10;
    	cairo_set_dash (cr, dash, 1, 0); // Affectation du trait discontinue déclaré dans le tableau dash
    	cairo_set_line_width (cr, 1); // Epaisseur du trait
    	cairo_set_source_rgb (cr, color->red, color->green, color->blue); // Affectation de la couleur récupérée en tant que donnée utilisateur
     
    	/*Dessin d'un trait autour du widget*/
    	cairo_move_to (cr, 0, 0);
    	cairo_line_to (cr, width, 0);
    	cairo_line_to (cr, width, height);
    	cairo_line_to (cr, 0, height);
    	cairo_line_to (cr, 0, 0);
    	cairo_stroke (cr);
     
    	return FALSE;
    }
     
    int
    main (int argc, char *argv[])
    {
    	GtkWidget *MainWindow=NULL;
    	GtkWidget *Grid = NULL;
    	GtkWidget *ChildWidget = NULL;
    	int i, j, k=0;
    	gchar *CaseNumber = NULL;
     
    	/* Déclaration de trois couleurs primaires pour exemple. */
    	GdkRGBA color [3];
    	color[0].red=1; color[0].green=0; color[0].blue=0;
    	color[1].red=0; color[1].green=1; color[1].blue=0;
    	color[2].red=0; color[2].green=0; color[2].blue=1;
     
    	gtk_init (&argc, &argv);
     
    	/*Création d'une fenêtre principale*/
    	MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     
    	/*Création d'une grille dont les cases sont homogènes*/
    	Grid = gtk_grid_new ();
    	gtk_grid_set_row_homogeneous (GTK_GRID(Grid), TRUE);
    	gtk_grid_set_column_homogeneous (GTK_GRID(Grid), TRUE);
    	gtk_container_add (GTK_CONTAINER(MainWindow), Grid);
     
    	for (j=0; j<3; j++)
    		for (i=0; i<3; i++)
    		{
    			/*Initialisation d'un GtkLabel comme widget enfant*/
    			CaseNumber = g_strdup_printf ("(%d,%d)", i,j);
    			ChildWidget = gtk_label_new (CaseNumber);
    			g_free (CaseNumber);
     
    			/*On affecte une fonction callback pour chaque widget enfant accrochée au signal "draw"*/
    			g_signal_connect (G_OBJECT (ChildWidget), "draw", (GCallback)draw_child_widget, &color[k]);
     
    			/*Finalement on insère le widget enfant dans la grille*/
    			gtk_grid_attach (GTK_GRID(Grid), ChildWidget, i, j, 1, 1);
     
    			// Pour que la couleur affectée soit cyclique
    			if (k<2) k++; else k=0;
    		}
     
    	g_signal_connect (G_OBJECT (MainWindow), "destroy", (GCallback)gtk_main_quit, NULL);
    	g_signal_connect (G_OBJECT (MainWindow), "delete-event", (GCallback)gtk_main_quit, NULL);
     
    	gtk_widget_show_all (MainWindow);
     
    	gtk_main ();
     
    	return 0;
    }

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur Web en Loisir
    Inscrit en
    Janvier 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web en Loisir

    Informations forums :
    Inscription : Janvier 2006
    Messages : 129
    Par défaut
    C'est juste pour te dire merci.
    Très intéressant (en tout cas pour moi qui débute)

    bonne journée

  3. #3
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut
    Merci pour ce code que je viens de récupérer.

    À partir de cette idée, on peut aussi colorier le fond :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    void style (GtkWidget *ChildWidget, cairo_t *cr,double rouge, double vert, double bleu)
    {
       	gdouble dash[2];
    	gint width = gtk_widget_get_allocated_width (ChildWidget);
    	gint height = gtk_widget_get_allocated_height (ChildWidget);
     
    	cairo_set_source_rgb (cr, rouge, vert, bleu); // Affectation de la couleur récupérée en tant que donnée utilisateur
        cairo_paint(cr);
     
    	dash[0]=5;
    	dash[1]=10;
    	cairo_set_dash (cr, dash, 1, 0); // Affectation du trait discontinue déclaré dans le tableau dash
    	cairo_set_line_width (cr, 1); // Epaisseur du trait
    	cairo_set_source_rgb (cr, 0, 0, 0);
     
    	/*Dessin d'un trait autour du widget*/
    	cairo_move_to (cr, 0, 0);
    	cairo_line_to (cr, width, 0);
    	cairo_line_to (cr, width, height);
    	cairo_line_to (cr, 0, height);
    	cairo_line_to (cr, 0, 0);
    	cairo_stroke (cr);
     
    }
    Je me pose une question quant aux paramètres des fonctions callback : j'ai l"impression qu'on peut mettre ce qu'on veut et c'est bon...Je fais un fil de discussion sur ce sujet :
    http://www.developpez.net/forums/d15...ions-callback/
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. comment avoir la date automatiquement
    Par champion dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 13/01/2005, 13h07
  2. Réponses: 3
    Dernier message: 08/08/2004, 21h35
  3. Comment avoir des marges dans un TRichEdit ?
    Par nomdutilisateur dans le forum Composants VCL
    Réponses: 5
    Dernier message: 25/06/2004, 09h57
  4. [eclipse][plugin] Comment avoir une fenêtre avec focus
    Par relivio dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 07/04/2004, 15h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo