IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

gerald3d

[GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ?

Noter ce billet
par , 22/03/2015 à 22h05 (1421 Affichages)
Bonjour à toutes et à tous.

Bon nombre d'entre-vous désirent obtenir une grille façon tableur. Je vous propose ici une solution à cet épineux problème .

La solution proposée s'appuie sur Gtk+v3.0.

Ce qu'il faut comprendre aujourd'hui avec Gtk+v3.0 c'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 neuf 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 c : 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;
}

Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Viadeo Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Twitter Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Google Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Facebook Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Digg Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Delicious Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog MySpace Envoyer le billet « [GTK+ v3.0] Comment avoir un GtkGrid ressemblant à un tableur ? » dans le blog Yahoo

Mis à jour 24/04/2016 à 20h45 par LittleWhite (Coloration code)

Catégories
Programmation , C

Commentaires

  1. Avatar de Luke spywoker
    • |
    • permalink
    Jolie implémentation d'un tableur avec des dash stroke multicolor comme séparateur.

    Bravo pour l'effort car ce n'est pas si évident que ça, je trouve, de dessiné avec GTK+3 car dans le seule bouquin sur GTK+ c'est la version 2 qui est présenter et le dessin se faisait avec une autre bibliothèque que cairo, et il n'y a pas beaucoup de tutoriels sur le sujet.
    Alors l'on se retrouve béas devant la doc de GTK+3.

    Je me posait la question si il est possible d'implémenter des animations dessinés avec GTK+3 ?
  2. Avatar de gerald3d
    • |
    • permalink
    Les GdkPixbuf implémentent quelques procédures pour créer des animations à base d'images.

    Sinon, il est toujours possible d'animer un dessin avec cairo. Mais la réponse ne viendra pas directement de cairo mais plutôt des algorithmes pour générer un dessin.