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 :

Zone de Dessin dans une fenêtre [GTK 3 & Cairo]


Sujet :

GTK+ avec C & C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut Zone de Dessin dans une fenêtre [GTK 3 & Cairo]
    Bonjour à tous.

    J'ai déjà souffert un peu avec les Drawing Area notamment parce que
    je travail sur la version 3 de GTK et que sur cette version on ne peut
    plus faire de : Widget->window, Widget->style et que même si je
    commence à peine à utiliser GTK la plupart des tutoriels sont faits
    sur la version 2 de GTK et n'utilise donc pas Cairo.


    Bref... Après recherche j'ai vu qu'il fallait utiliser cairo pour faire des
    DrawingArea. Plusieurs tutoriels sur le net expliquent bien comment
    procéder mais aucun d'entres eux ne dit comment créer un zone de
    dessin dans une fenêtre et pas faire de la fenêtre une zone de dessin
    entière...


    Par exemple je sais que je peux dessiner une zone de dessin (couleur
    jaune ici) à l'aide du code suivant, seulement toute la fenêtre sera une
    DrawingArea ce que je ne veux pas :

    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
    #include <gtk/gtk.h>
    #include <cairo.h>
     
    typedef struct Info {
      GtkWidget * win;
      cairo_t * cairo;
    } Info;
     
    gboolean on_expose_color (GtkWidget * widget, GdkEvent * e, gpointer data) {
      Info * info= data;
      cairo_pattern_t * yellow;
      double red, green, blue, alpha;
     
      info->cairo= gdk_cairo_create (gtk_widget_get_window(widget));
      red= 1.0; green= 1.0; blue= 0.0; alpha= 1.00;
      yellow= cairo_pattern_create_rgba (red, green, blue, alpha);
      cairo_set_source (info->cairo, yellow);
      cairo_paint (info->cairo);
     
      cairo_pattern_destroy (yellow);
      cairo_destroy (info->cairo);  info->cairo= NULL;
      return TRUE;
    }
     
     
    void info_init (Info * info, GtkWidget * win)  {
      info->win  = win;
      info->cairo= NULL;
    }
     
    int main (int argc, char * argv [])
    {
      Info info;
      GtkWidget * win;
      gtk_init (& argc, & argv);
      win= gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_size_request (win, 200, 200);
      info_init (& info, win);
      g_signal_connect (win, "draw", G_CALLBACK (on_expose_color), & info);
     
      gtk_widget_show_all (win);  
      gtk_main ();
      return 0;
    }
    Je voulais remplacer la ligne info->cairo... par :
    info->cairo= gdk_cairo_create (gtk_widget_queue_draw_area(widget, 2, 5, 50, 20));

    mais gtk_widget_queue_draw_area renvoie pas une GtkWindow mais rien (void) donc
    cela fait une erreur... je vois pas du tout comment faire.

    Note :
    Widget->window est remplacé par gtk_widget_get_window(widget) dans GTK 3.


    Dans l'absolu ce qui serait encore mieux c'est que quand je clique sur l'icône "Nouveau"
    de ma barre d'outils une zone de dessin sur fond noire apparaissent sur une partie
    de ma fenêtre principale...

    Merci par avance
    Bonne soirée

  2. #2
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Citation Envoyé par Twice22 Voir le message
    même si je
    commence à peine à utiliser GTK la plupart des tutoriels sont faits
    sur la version 2 de GTK et n'utilise donc pas Cairo.
    Cairo est utilisé depuis GTK 2.8, soit depuis 2005... Il y a des tutoriels GTK et cairo, mais ceux sur développez.net ne sont pas forcément les plus à jour.

    Citation Envoyé par Twice22 Voir le message
    Bref... Après recherche j'ai vu qu'il fallait utiliser cairo pour faire des
    DrawingArea. Plusieurs tutoriels sur le net expliquent bien comment
    procéder mais aucun d'entres eux ne dit comment créer un zone de
    dessin dans une fenêtre et pas faire de la fenêtre une zone de dessin
    entière...
    Je ne sais pas si j'ai tout bien compris, mais a priori tu n'as qu'à ajouter une GtkDrawingArea dans ton interface, te connecter à son événement "draw", et dessiner dans la callback associée. Si dans ton exemple tu dessines dans toute la GtkWindow, c'est parce que tu es connecté à son événement draw.

    Pour ce qui est de dessiner un sous ensemble du widget auquel tu as connecté l'événement draw, gtk_widget_queue_draw te permet d'indiquer que le widget entier doit être redessiné (parce que les données qu'il affiche ont changé par exemple). En retour, cette fonction va émettre le signal "draw" pour ton widget, et ta callback va l'intercepter, te permettant de redessiner le widget entier.

    Si une modification des données à afficher ne doit provoquer la modification que d'une partie de ton widget, alors tu peux appeler gtk_widget_queue_draw_area en spécifiant les coordonnées de cette zone. Cette fonction va émettre le signal "draw" pour ton widget, ta callback va l'intercepter, et dans les paramètres d'entrée, tu peux récupérer les coordonnées de la zone à redessiner (et utiliser les fonctions de clipping de cairo, qui accélèreront l'affichage en ne dessinant que le strict nécessaire).

    J'ai écrit il y a quelques temps un exemple simple de dessin avec GTK et cairo. C'est pour GTK 2, mais la seule différence c'est que le signal "expose-event" de GTK 2 est devenu "draw" dans GTK 3. D'ailleurs, je te conseille de renommer ta callback en on_draw plutôt que on_expose_color...
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut
    Ce que je veux faire c'est créer une drawingArea dans ma fenêtre principale qui ne prenne pas toute la place de la fenêtre. Ainsi j'aurais par exemple des boutons situé sur la gauche de ma fenêtre et sur la droite un rectangle (noir) qui est ma drawing area dans laquelle je pourrais dessiner des choses quand j'appuyerai sur mes boutons...


    Je cherchais une fonction du côté de Cairo pour créer une drawingArea d'une certaine dimension dans ma fenêtre mais en fait il faut plutôt que je créé mes boutons et ma drawing area séparement et que je les attache à une table (Grid en GTK 3) ?

    En effet si je dis par exemple : "Je veux créer une une zone de dessin rectangulaire de 200 par 500 pixels dans ma fenêtre principale dont le coin supérieur de ma zone de dessin est situé aux coordonnées (20,20) de ma fenêtre principale" ben quand je redimensionnerai la fenêtre... le programme ne
    captera pas... c'est pour ça qu'il ont créé des tables je pense d'ailleurs ?

    J'ai tenté de faire un petit quelque chose mais... cela ne fonctionne pas.
    Comme mis en commentaire du code je pense qu'il faut passer area dans
    le g_signal_connect mais si je passe area rien ne se colorie...

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <cairo.h>
     
     
     
    gboolean on_draw (GtkWidget *widget, GdkEventExpose *event, gpointer data) 
    {
     
      cairo_t *cr = gdk_cairo_create (gtk_widget_get_window(widget));
      GdkRectangle da;           //Dimensions de la GtkDrawingArea */
     
      /* bizarrement il n'y a pas le paramètre depth comme marqué dans le manuel officiel... */
      gdk_window_get_geometry (gtk_widget_get_window(widget), &da.x, &da.y, &da.width, &da.height);
     
      /* affiche dans la console les dimension de ma GTK_GRID */
      printf("x = %d, y = %d, width = %d, height = %d\n", da.x, da.y, da.width, da.height);
     
      cairo_set_source_rgb (cr, 0.0 , 0.0 , 0.0); //fond noir
      cairo_paint (cr);
     
      cairo_destroy (cr);
      return FALSE;
    }
     
     
    int main (int argc, char * argv [])
    {
      GtkWidget * win;
      GtkWidget * area;
      GtkWidget * table;
     
      gtk_init (& argc, & argv);
     
     
      /* description de la fenetre */
      win= gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_size_request (win, 800, 600);
      g_signal_connect (G_OBJECT(win), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
      /* Créatione st insertion de zone de dessin dans la table */
      table = gtk_grid_new();
      gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(table));
     
      /* Création de la table */
      area = gtk_drawing_area_new ();
      gtk_grid_attach(GTK_GRID (table), area, 0, 0, 1, 1);
      // gtk_container_add (GTK_CONTAINER (win), area);  
     
      /* j'avais mis area au lieu de table comme premier paramètre mais 
      dans ce cas la fenetre ce colorie pas... */
      g_signal_connect (G_OBJECT (table), "draw", G_CALLBACK (on_draw), NULL);
     
      gtk_widget_show_all (win);  
      gtk_main ();
      return 0;
    }

  4. #4
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Un conseil, ne t'enferme pas dans des tailles fixes, c'est le meilleur moyen d'avoir une interface ultra-rigide. Ce qui te conviendrait le mieux, c'est une interface avec tes boutons, tes actions, et une GtkDrawingArea qui prend toute la place disponible restante. Pour cela tu dois jouer avec le paramètre expand de gtk_box_pack_start, qui dit au widget de prendre la place supplémentaire disponible, ou bien fais la même chose avec GtkGrid. Si tous les modèles de dimensionnement sont dynamiques dans GTK, c'est pour éviter les fenêtres où tout était placé au pixel près, et qui ne s'adaptaient plus dès que tu agrandissais ou rétrécissais la fenêtre (et j'ai pas mal souffert sous Windows en MFC avec ça).

    Et pour garder le dessin à la bonne échelle dans ta GtkDrawingArea, utilise les matrices de transformation cairo, comme je l'ai fait dans l'exemple de graphique en cairo dont je t'ai filé le lien.
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  5. #5
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 329
    Points : 606
    Points
    606
    Par défaut
    Il me semble que ce que tu veux faire, c'est diviser ta fenêtre principale en deux, par exemple en créant deux GtkBox, l'une qui contiendra tes boutons et l'autre ta DrawingArea.
    Avec GTK il ne faut pas hésiter à créer autant de boites que nécessaire pour obtenir la mise en page désirée.
    GraceGTK: a plotting tool at https://sourceforge.net/projects/gracegtk

  6. #6
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Je viens de regarder ton code, tu fais aussi une erreur: le prototype de la callback on_draw est erroné. Tu utilises le prototype de la callback associée au signal expose-event, mais celui ci n'existe plus. Tu dois regarder la doc GTK 3 pour connaître le prototype à utiliser. Par exemple pour GtkWidget::draw:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gboolean user_function (GtkWidget *widget, CairoContext *cr, gpointer user_data)
    C'est d'ailleurs une des raisons de la rupture de compatibilité de GTK 3: tu travailles nativement avec cairo, plus besoin de faire des conversions de contexte graphique GDK en contexte cairo avec gdk_cairo_create, ni d'appeler cairo_destroy. C'est plus propre et plus efficace.

    Pour un exemple concret, regarde la doc de GtkDrawingArea dans GTK 3.

    Perso j'ai une erreur avec CairoContext, mais en remplaçant par le type normal d'un contexte cairo (cairo_t) ça fonctionne chez moi. Peut être un bug de la doc à ce niveau là.

    Autre remarque: utilise gtk_window_set_default_size plutôt que gtk_widget_set_size_request, sinon tu empêches le redimensionnement à une taille plus petite...

    Si tu n'arrivais pas à dessiner directement dans le GtkDrawingArea, c'est parce qu'il a une taille de 1x1 pixel. C'est parce que la manière de définir la place occupée par un widget (s'il s'étend ou pas, horizontalement, verticalement) a changé avec GtkGrid pour la rendre plus homogène. Tu as un tutoriel de la doc GTK qui t'explique les différences entre GtkBox et GtkGrid.

    Ce qui donne au final:
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <cairo.h>
     
     
    gboolean on_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) 
    {
      /* affiche dans la console les dimensions du widget */
      printf("width = %d, height = %d\n",
    		  gtk_widget_get_allocated_width(widget),
    		  gtk_widget_get_allocated_height(widget));
     
      cairo_set_source_rgb (cr, 0.0 , 0.0 , 0.0); //fond noir
      cairo_paint (cr);
     
      return FALSE;
    }
     
     
    int main (int argc, char * argv [])
    {
      GtkWidget * win;
      GtkWidget * area;
      GtkWidget * table;
     
      gtk_init (&argc, &argv);
     
     
      /* description de la fenetre */
      win= gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_default_size (GTK_WINDOW (win), 800, 600);
      g_signal_connect (G_OBJECT(win), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
      /* Création et insertion de zone de dessin dans la table */
      table = gtk_grid_new();
      gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(table));
     
      /* Création de la table */
      area = gtk_drawing_area_new ();
      gtk_grid_attach(GTK_GRID (table), area, 0, 0, 1, 1);
     
      /* On indique que la drawing area prend le maximum de place disponible */
      gtk_widget_set_hexpand (area, TRUE);
      gtk_widget_set_vexpand (area, TRUE);
      g_signal_connect (G_OBJECT (area), "draw", G_CALLBACK (on_draw), NULL);
     
      gtk_widget_show_all (win);  
      gtk_main ();
      return 0;
    }
    Pour éviter ces problèmes de placement de widget, je t'assure, teste Glade
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut
    Bonjour. Je viens de compiler votre code. Il fonctionne mais il ne fait pas ce que je souhaite.
    Je m'explique peut-être mal mais je souhaite que ma DrawingArea ne prenne pas toute la place de ma fenêtre principale mais seulement une partie. Quand je compile votre code modifié j'ai toute la fenêtre qui est colorié en noir (donc ma GtkDrawingArea remplie toute la fenêtre ?).

    Je pensais qu'en mettant ma drawingArea dans une Grille à l'aide de la fonction
    gtk_grid_attach Je pouvais avoir ce que je voulais...


    J'ai compris que les paramètres qu'il faut rentrer dans la
    gtk_grid_attach étaient les nombres de colonnes et de lignes qui séparent
    mon Widget des bordures... seulement si on a pas dit en combien de colonnes
    je subdivise ma fenêtre principale comment le programme peut effectivement placer
    ma fenêtre...

    Edit : J'arrive à faire presque ce que je veux.
    Le problème c'est qu'avec GTK 3 ben quand je redimensionne ma fenêtre la zone
    allouée pour ma drawingArea ne se redimensionne pas en prenant le même pourcentage
    d'espace vu que je suis apparemment obligé de donner la taille en pixels séparant les
    colonnes et que je peux pas plutôt subdiviser mon espace en colonne dont l'espacement
    s'adapte avec le redimensionnement de la fenêtre...

    En outre j'ai encore un problème.. Je veux mettre ma DrawingArea au milieu à droite et
    pas en haut à gauche mais quand je change les paramètre left et top de gtk_grid_attach
    ma drawingArea reste en haut à gauche... Voilà le code :

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <cairo.h>
     
     
     
    gboolean on_draw (GtkWidget *widget, cairo_t *cr, gpointer data) 
    {
     
      /* affiche dans la console les dimensions du widget */
      printf("width = %d, height = %d\n",
    		  gtk_widget_get_allocated_width(widget),
    		  gtk_widget_get_allocated_height(widget));
     
     
      cairo_set_source_rgb (cr, 0.0 , 0.0 , 0.0); //fond noir
      cairo_paint (cr);
     
      //cairo_destroy (cr);
      return FALSE;
    }
     
     
    int main (int argc, char * argv [])
    {
      GtkWidget * win;
      GtkWidget * area;
      GtkWidget * table;
     
      gtk_init (& argc, & argv);
     
     
      /* description de la fenetre */
      win= gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_size_request (win, 800, 600);
      g_signal_connect (G_OBJECT(win), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
      /* Créatione st insertion de zone de dessin dans la table */
      table = gtk_grid_new();
      gtk_grid_set_row_spacing (GTK_GRID (table), 10);
      gtk_grid_set_column_spacing (GTK_GRID(table), 10);
      gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(table));
     
      /* Création de la table */
      area = gtk_drawing_area_new ();
      gtk_grid_attach(GTK_GRID (table), area, 300, 200, 6, 40);
      // gtk_container_add (GTK_CONTAINER (win), area);  
     
      /* j'avais mis area au lieu de table comme premier paramètre mais 
      dans ce cas la fenetre ce colorie pas... */
      //gtk_widget_set_hexpand (area, TRUE);
      //gtk_widget_set_vexpand (area, TRUE);
      // gtk_grid_insert_column (GTK_GRID(table), 200);
      g_signal_connect (G_OBJECT (area), "draw", G_CALLBACK (on_draw), NULL);
     
      gtk_widget_show_all (win);  
      gtk_main ();
      return 0;
    }

    Merci.
    Merci

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Tu te trompes dans les arguments de gtk_grid_attach: les valeurs ne sont pas des pixels, ce sont des indices de colonnes et de lignes séparant tes widgets. Forcément, la drawing area prend tout l'espace disponible si on met hexpand et vexpand TRUE. Mais ajoute d'autre widgets dans la GtkGrid, sinon tu ne comprendras jamais comment ça marche...
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut
    Oui, je sais que c'est des colonnes et des lignes que prend les paramètres de
    la fonction gtk_grid_attach. J'ai lu la documentation en long en large et en travers... Seulement comment partitionner ma fenêtre en ligne et en colonne ?


    Si je peux pas partitionner ma fenêtre en lignes et en colonnes alors comment
    je peux utiliser la fonction gtk_grid_attach ? Je ne sais pas combien il y a de
    colonnes et de lignes dans ma fenêtre donc les 4 derniers paramètre de ma
    fonction gtk_grid_attach n'ont aucun intérêt... ? Je ne vois pas du tout. j'ai
    cherché dans la documentation s'ils y avait des fonctions de création de
    colonnes et de lignes mais à part les fonctions d'insertion d'UNE colonne ou
    d'UNE ligne à un emplacement précis de la fenêtre définie en pixels je n'ai rien
    trouvé...


    En GTK 2 c'était je pense plus simple car on pouvait partitionner la fenêtre en
    lignes et en colonnes directement en écrivant : gtk_table_new(15,20,TRUE)
    pour avoir 15 lignes, 20 colonnes et que celle-ci soient espacées de manière
    homogène... Ici la fonction de création d'une grille ne prend aucun paramètre
    alors j'ai du mal à voir comment faire pour placer mes widgets et à comprendre
    pourquoi les développeurs ont voulu complexifier la manière d'organiser la
    fenêtre ?

    Ainsi moi j'aimerai une fenêtre du style :


    Et j'ai vu qu'avec Glade et GTK 3 on pouvait créer une grille de x lignes et
    y colonnes comme suit (traits en gris) et y placer une DrawingArea (Zone
    noire) qui recouvre x' lignes et y' colonnes et qui est située à u' lignes du haut
    et à v' colonnes du côté gauche de la fenêtre (u',v',x',y' sont des paramètres
    de la fonction gtk_grid_attach...). Seulement encore une fois comment est-ce
    que je peux partitionner ma fenêtre en x lignes et y colonnes puisque la
    fonction gtk_grid_new ne prend aucune paramètre comme le faisait la
    fonction gtk_table_new et que je n'ai pas trouvé de fonctions pour subdiviser
    l'espace en x lignes et y colonnes.... Ainsi je peux passer n'importe quoi
    comme valeur pour u', v', x' et y' ça ne changera rien vu que ma fenêtre n'est
    pas préalablement partitionner....

    Voilà un exemple de ce que j'ai pu faire en Glade


    Ainsi je voudrais refaire ce que j'ai pu faire sur Glade à la main mais je ne vois
    pas comment... De plus depuis Glade 3 on ne peut pas générer de code en .c
    j'ai vu sur internet donc pas possible de voir qu'elle fonction utiliser pour
    partitionner ma fenêtre en x lignes et y colonnes.


    Je me suis pas mal répété mais c'est pour bien vous expliquer mon problème.

    Merci.

  10. #10
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Le découpage en lignes et colonnes ne se fait pas en créant des zones à espacement identiques. Le but est de créer une colonne à chaque fois que tu arrives au bord gauche ou droite d'un widget, et une ligne à chaque fois que tu arrives au bord supérieur ou inférieur d'un widget. Tu numérotes tes lignes et colonnes de 0 à n, et tu ajoutes tes widgets dans le GtkGrid en indiquant dans quel rectangle ils sont contenus. Le rectangle en question est défini par les n° de colonnes qui le délimitent à gauche et à droite, et les n° de ligne qui le délimitent en haut et en bas.



    Évidemment, tu n'auras le bon résultat final que si tu ajoutes tous tes widgets, vu que les lignes ou colonnes vides seront fusionnées, et auront une épaisseur nulle... Donc comme je te l'ai déjà dit, ajoute tous tes widgets pour voir ce que ça donne ! Un widget se place par rapport aux autre, pas de manière absolue comme tu cherches à le faire.
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut
    Ok merci je vais essayer de faire cela demain.
    Néanmoins en GTK 2 on peut le faire de manière absolue
    il me semble au vu des fonctions autorisées...

  12. #12
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    En GTK 3 aussi. Il suffit d'utiliser GtkLayout, comme en GTK 2. Mais c'est juste nul. Tout ce qui est placement absolu est néfaste, parce ce que tu vas te retrouver avec des bugs dès que tu vas redimensionner ta fenêtre, ou te retrouver avec de la place perdue pour rien. Et c'est pas moi qui vais enseigner à faire du boulot de sagouin...
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  13. #13
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut
    Ah ok... Merci en tout cas.

    Je comprends donc mieux la chose et j'ai pu pondre à la va vite (j'ai pas mal d'autres choses à faire pour demain) du code avec plus-ou-moins ce que je souhaitais avoir :

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <cairo.h>
     
     
     
    gboolean on_draw (GtkWidget *widget, cairo_t *cr, gpointer data) 
    {
     
      /* affiche dans la console les dimensions du widget */
      printf("width = %d, height = %d\n",
    		  gtk_widget_get_allocated_width(widget),
    		  gtk_widget_get_allocated_height(widget));
     
     
      cairo_set_source_rgb (cr, 0.0 , 0.0 , 0.0); //fond noir
      cairo_paint (cr);
     
      //cairo_destroy (cr);
      return FALSE;
    }
     
     
    int main (int argc, char * argv [])
    {
      GtkWidget * win;
      GtkWidget * area;
      GtkWidget * table;
     
      /* Widget nb de sommets */
      GtkWidget * frame;
      GtkWidget *nbSommet;
     
      /* Widget style de sommets */
      GtkWidget * styleSom;
      GtkWidget * boutonP;
      GtkWidget * boutonD;
     
      /* Widget GO */
      GtkWidget * Go;
     
      gtk_init (& argc, & argv);
     
     
      /* description de la fenetre */
      win= gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_size_request (win, 800, 600);
      g_signal_connect (G_OBJECT(win), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
      /* Créatione st insertion de zone de dessin dans la table */
      //table = gtk_grid_new();
      table = gtk_grid_new ();
      gtk_grid_set_column_homogeneous(GTK_GRID(table), TRUE);
      gtk_grid_set_row_homogeneous(GTK_GRID(table), TRUE);
      gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(table));
     
      /* Widget nombre de sommet */
      frame = gtk_frame_new("Nombre de sommets");
      nbSommet = gtk_spin_button_new_with_range(0,5000,1);
     
      /* Widget style de points */
      styleSom = gtk_label_new("Style des sommets :");
      boutonP = gtk_radio_button_new_with_label(NULL, "Points");
      boutonD = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(boutonP), "Disques");
      Go = gtk_button_new_from_stock(GTK_STOCK_OK);
     
      /* Création de la table */
      area = gtk_drawing_area_new ();
      gtk_grid_attach(GTK_GRID (table), frame, 1, 1 ,3 ,1 );
      gtk_grid_attach(GTK_GRID (table), nbSommet, 1, 3 ,3 ,1 ); 
      gtk_grid_attach_next_to(GTK_GRID (table), area, nbSommet, GTK_POS_RIGHT, 15, 13); 
      gtk_grid_attach_next_to(GTK_GRID (table), styleSom, nbSommet, GTK_POS_BOTTOM, 3, 1);
      gtk_grid_attach_next_to(GTK_GRID (table), boutonP, styleSom, GTK_POS_BOTTOM, 1, 1);
      gtk_grid_attach_next_to(GTK_GRID (table), boutonD, boutonP, GTK_POS_RIGHT, 1, 1);
      gtk_grid_attach_next_to(GTK_GRID (table), Go, boutonP, GTK_POS_BOTTOM, 3, 1);
     
      /* j'avais mis area au lieu de table comme premier paramètre mais 
      dans ce cas la fenetre ce colorie pas... */
      //gtk_widget_set_hexpand (area, TRUE);
      //gtk_widget_set_vexpand (area, TRUE);
      g_signal_connect (G_OBJECT (area), "draw", G_CALLBACK (on_draw), NULL);
     
      gtk_widget_show_all (win);  
      gtk_main ();
      return 0;
    }
    Bien sûr il est pas très très clean encore mais bon je dois faire d'autres choses.


    J'ai encore une dernière petite question. Comment est-ce que je peux ajouter une bordure
    entre ma DrawingArea et mes bords supérieurs, inférieurs et droit de ma fenêtre (i.e.
    comme est-ce que je peux laisser une colonne d'espacement entre mes bords de ma
    DrawingArea et mes bords de ma fenêtre ?). Faut-il ajouter des Widget qu'y ne contiennent
    rien ? Comment le faire proprement ?

    Merci.

  14. #14
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    C'est encore une fois expliqué dans la documentation:
    https://developer.gnome.org/gtk3/stable/ch29s03.html
    Documentation officielle GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels GTK+ 3:
    GTK en C, GTK en Python

    Tutoriels par l'exemple (platform-demos):
    GTK (tous langages)

  15. #15
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 38
    Points : 16
    Points
    16
    Par défaut
    J'ai pas pu répondre avant désolé.
    Le lien que vous m'avez passé m'est utile.
    Le problème c'est que je voulais quelque chose
    qui travaille sur le nombre de colonnes qui sépare
    mon Widget du bord de la fenêtre principale.
    Apparement à part ajouter un widget vide qui
    prend 1 colonne de place il n'y a pas.

    C'est la première fois que j'utilise la documentation
    d'une librairie. D'habitude il y a pas mal de tutoriels
    et c'est plus facile. Même si je cherche j'ai un peu
    de mal à tout voir. Merci encore.

    PS : J'ai testé l'ajout de colonne et de ligne à
    côté d'un widget pour rajouter une 'bordure' de la
    largeur d'une colonne mais ça ne fonctionne pas.

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

Discussions similaires

  1. [Virtual Pascal] Dessiner dans une fenêtre avec la librairie OWL
    Par Roland Chastain dans le forum Autres IDE
    Réponses: 15
    Dernier message: 31/08/2012, 19h15
  2. Dessin dans une autre fenêtre
    Par Harmo dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 10/05/2010, 16h00
  3. Dessiner dans une fenêtre externe à mon application
    Par fatdarron dans le forum Langage
    Réponses: 6
    Dernier message: 15/03/2010, 15h13
  4. Réponses: 2
    Dernier message: 09/02/2008, 01h23
  5. problème de dessin dans une fenêtre
    Par Mat 74 dans le forum Windows
    Réponses: 8
    Dernier message: 12/04/2007, 11h44

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