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 :

scroll bar et implémentation dynamique dans une gtk_vbox


Sujet :

GTK+ avec C & C++

  1. #1
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Points : 84
    Points
    84
    Par défaut scroll bar et implémentation dynamique dans une gtk_vbox
    Bonjour à tous,

    J'ai un double problème avec le code suivant, qui concerne l'usage des gtk_scrolled_window et l'ajout dynamique d'éléments dans une gtk_box. Peut-être dois-je faire ici deux posts différents (si tel est le cas, merci de me le dire, je modifierai ce post), mais il me semble que ces deux problèmes sont liés. Le code suivant est un code exemple qui montre de quoi il s'agit :

    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
    /* travail sur les scrolled barres et les implémentations dynamiques de v box */
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include <string.h>
     
    GtkWidget* vbox; /* v box princale */
    GtkWidget* vbox2;
    GtkAdjustment *verticalAdjust;
    GtkWidget* barre; /* scrolled windows */
     
    int main(int argc,char **argv)
    {
        GtkWidget* pWindow;
        GtkWidget* pLabel[20];
        GtkWidget* boutton;
        int i;
        char tempo[20];
     
        void suite(GtkWidget *widget, gpointer pData); /* fonction call back si boutton clicked */
     
        gtk_init(&argc,&argv);
        pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(pWindow), "scrolled barre et construction de vbox");
        gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
        /* Creation des labels */
        for (i=0; i<20;i++)
        {
                pLabel[i]=gtk_label_new(NULL);
                (void)sprintf(tempo,"label %2d",i);
                gtk_label_set_text (pLabel[i], tempo);
        }
        /* on les mets dans une v box */
        vbox2=gtk_vbox_new(FALSE, 0);
        for (i=0; i<20;i++)
            gtk_box_pack_start(GTK_BOX(vbox2), pLabel[i], TRUE, TRUE, 0);
        /* creation d'une autre v box (principale) */
        vbox=gtk_vbox_new(FALSE, 0);
        /* creation du widget avec barre de défilement */
        barre=gtk_scrolled_window_new(NULL, NULL);
        /* on ne veux que la barre verticale - if needed */
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(barre), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
        /* on ne veux pas de bord autour */
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(barre), GTK_SHADOW_NONE);
        /* on met la barre à droite */
        gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(barre), GTK_CORNER_BOTTOM_RIGHT);
        /* on déroule tout en bas */
        verticalAdjust=gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(barre));
        gtk_adjustment_set_value(verticalAdjust, verticalAdjust->upper);
        gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(barre), verticalAdjust);
        /* creation d'un bouton et on le met dans la v box principale */
        boutton=gtk_button_new_with_label("ajout d'un label");
        gtk_box_pack_start(GTK_BOX(vbox), boutton, FALSE, FALSE, 0);
        /* on met la v box dans le widget avec barre de défilement*/
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(barre), vbox2);
        /* On ajoute le widget avec barre de défilement a l'intérieur de la v box principale */
        gtk_box_pack_start(GTK_BOX(vbox), barre, TRUE, TRUE, 0);
        gtk_container_add(GTK_CONTAINER(pWindow), vbox);
        /* Connexion des signaux */
        g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
        g_signal_connect(G_OBJECT(boutton), "clicked", G_CALLBACK(suite), NULL);
        /* Affichage de la fenêtré et de tout ce qu'il contient */
        gtk_widget_show_all(pWindow);
        gtk_main();
        return EXIT_SUCCESS;
    }
    void suite(GtkWidget *window, gpointer data)
    {
        GtkWidget* label=NULL;
        label=gtk_label_new("un autre label");
        /* on rajoute un élément à la v box */
        gtk_box_pack_start(GTK_BOX(vbox2),label, TRUE, TRUE, 0);
        /* et on déroule tout en bas */
        verticalAdjust = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(barre));
        gtk_adjustment_set_value(verticalAdjust, verticalAdjust->upper);
        gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(barre), verticalAdjust);
    }
    Cliquer sur le bouton, comme vous pouvez le voir, a deux missions :

    1) Rajouter un label à la box verticale, et
    2) scrolling tout en bas la scroll barre.

    Les deux questions que j'ai sont les suivantes :

    1) Les lignes de code 46 à 49 doivent faire un scrolling tout en bas par défaut (avant tout click sur le bouton) de la scroll barre. Ca ne fonctionne pas. Seul un(des) click(s) sur le bouton (i.e., le code de la fonction callback) le fait correctement. Pourquoi ? C'est exactement le même code qu'il y a aux deux endroits !

    2) L'ajout d'un label à la box verticale (fait dans la fonction callback) ne fonctionne pas. Pourquoi ? Ne peut-on pas ajouter quelque chose à un gtk_box une fois qu'elle est insérée dans un widget ? Si oui, comment fait alors ? Doit-on tout "démonter", ajouter, et tout "remonter" ? Ca me parait bien lourd.

    Merci d'avance pour toute aide sur ces deux points.

    Cordialement, Eric.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut
    Pour ce qui est de rajouter le label, il manque simplement un gtk_widget_show(label); dans la fonction suite pour réaliser le label rajouté.

    aussi ligne 30: rajouter GTK_LABEL()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gtk_label_set_text (GTK_LABEL(pLabel[i]), tempo);
    GraceGTK: a plotting tool at https://sourceforge.net/projects/gracegtk

  3. #3
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par pvincent Voir le message
    Pour ce qui est de rajouter le label, il manque simplement un gtk_widget_show(label); dans la fonction suite pour réaliser le label rajouté.

    aussi ligne 30: rajouter GTK_LABEL()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gtk_label_set_text (GTK_LABEL(pLabel[i]), tempo);
    Ok, merci beaucoup! Ceci répond effectivement à ma seconde question.

    Reste à résoudre l'énigme (pour moi) de la première. Pourquoi les lignes 46 à 49 de mon code, qui ont pour objet de faire un scrolling tout en bas par défaut de la slide barre, ne fonctionnent pas ?

    Cordialement,

    Eric.

  4. #4
    Membre régulier
    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
    Points : 100
    Points
    100
    Par défaut
    salut,

    Pour que tu puisses modifier les Adjustment de la scrollbar, il faut que le widget scrolled window soit dessiné.
    Place un gtk_widget_show(barre) (ou show_all(pwindow) ) avant de modifier l'adjustment.

  5. #5
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par rollbich Voir le message
    salut,

    Pour que tu puisses modifier les Adjustment de la scrollbar, il faut que le widget scrolled window soit dessiné.
    Place un gtk_widget_show(barre) (ou show_all(pwindow) ) avant de modifier l'adjustment.
    Merci,

    Je viens de faire plusieurs essais. Ca ne fonctionne pas. Un gtk_widget_show(barre) avant ne change rien. Et dérouler la scroll bar tout en bas après le gtk_widget_show_all(pWindow) ne fonctionne pas non plus.

    J'ai loupé quelque chose ?

    Encore merci pour toute aide sur ce point!

    Eric.

  6. #6
    Membre régulier
    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
    Points : 100
    Points
    100
    Par défaut
    salut,

    J'ai compilé ton code (j'ai dû enlever verticalAdjust->upper et le remplacer par une valeur car je suis sous gtk3 et ça doit plus exister)

    Le code suivant fonctionne chez moi :

    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
    /* travail sur les scrolled barres et les implémentations dynamiques de v box */
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include <string.h>
     
    GtkWidget* vbox; /* v box princale */
    GtkWidget* vbox2;
    GtkAdjustment *verticalAdjust;
    GtkWidget* barre; /* scrolled windows */
     
    int main(int argc,char **argv)
    {
        GtkWidget* pWindow;
        GtkWidget* pLabel[20];
        GtkWidget* boutton;
        int i;
        char tempo[20];
     
        void suite(GtkWidget *widget, gpointer pData); /* fonction call back si boutton clicked */
     
        gtk_init(&argc,&argv);
        pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(pWindow), "scrolled barre et construction de vbox");
        gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
        /* Creation des labels */
        for (i=0; i<20;i++)
        {
                pLabel[i]=gtk_label_new(NULL);
                (void)sprintf(tempo,"label %2d",i);
                gtk_label_set_text (pLabel[i], tempo);
        }
     
        vbox2=gtk_vbox_new(FALSE, 0);
        for (i=0; i<20;i++)
            gtk_box_pack_start(GTK_BOX(vbox2), pLabel[i], TRUE, TRUE, 0);
     
        vbox=gtk_vbox_new(FALSE, 0);
     
        barre=gtk_scrolled_window_new(NULL, NULL);
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(barre), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(barre), GTK_SHADOW_NONE);
     
        boutton=gtk_button_new_with_label("ajout d'un label");
        gtk_box_pack_start(GTK_BOX(vbox), boutton, FALSE, FALSE, 0);
        /* on met la v box dans le widget avec barre de défilement*/
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(barre), vbox2);
        /* On ajoute le widget avec barre de défilement a l'intérieur de la v box principale */
        gtk_box_pack_start(GTK_BOX(vbox), barre, TRUE, TRUE, 0);
        gtk_container_add(GTK_CONTAINER(pWindow), vbox);
        /* Connexion des signaux */
        g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
        /* Affichage de la fenêtré et de tout ce qu'il contient */
        gtk_widget_show_all(pWindow);
        verticalAdjust=gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(barre));
        gtk_adjustment_set_value(verticalAdjust, 120);
        gtk_main();
        return EXIT_SUCCESS;
    }
    Comme je te l'avais indiqué, si tu places le gtk_adjustment_set_value avant le gtk_widget_show_all, ça marche pas

  7. #7
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par rollbich Voir le message
    salut,

    J'ai compilé ton code (j'ai dû enlever verticalAdjust->upper et le remplacer par une valeur car je suis sous gtk3 et ça doit plus exister)

    Le code suivant fonctionne chez moi :

    Comme je te l'avais indiqué, si tu places le gtk_adjustment_set_value avant le gtk_widget_show_all, ça marche pas
    Bon, on avance, merci. Mais je ne comprends toujours pas. Deux choses restent à résoudre :

    1) Votre code marche alors que vous avez viré la ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(barre), verticalAdjust);
    Pourtant - dans ma compréhension - c'est cette instruction qui devrait justement rendre effective la modification de valeur de la struct GtkAdjustment. Une explication ?

    2) Effectivement, votre code fonctionne si on remplace verticalAdjust->upper par une constante, et vous dites que vous faites ca car vous êtes sous gtk3. Mais, c'est bien sous gtk3 que "upper" est défini dans la documentation officielle comme un élément de la struct GtkAdjustment (GtkAdjustment). Si je remets "verticalAdjust->upper" dans votre code, ca plante. Or ca marche s'il est dans une fonction callback (comme dans mon code initial). Il réside bien une énigme à résoudre ici.

    Encore merci pour toute aide sur ce point!

    Eric.

  8. #8
    Membre régulier
    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
    Points : 100
    Points
    100
    Par défaut
    Chez moi, j'ai une erreur à la compilation pour verticalAdjust->upper.
    Ce qui semble tout à fait normal car on peut lire dans la doc gtk3 :
    struct GtkAdjustment;
    The GtkAdjustment struct contains only private fields and should not be directly accessed.
    Les champs sont privés, par conséquent non accessibles.

    Je ne comprends pas pourquoi tu n'as pas d'erreur à la compil et pourquoi ça semble marcher dans la callback (j'ai pas testé)

    Si tu n'as besoin de changer que la position de la scrollbar, utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gtk_adjustment_set_value
    qui est là pour ça.

    Utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gtk_scrolled_window_set_vadjustment
    si tu souhaites modifier tous les paramètres de la scrollbar.

  9. #9
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par rollbich Voir le message
    Si tu n'as besoin de changer que la position de la scrollbar, utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gtk_adjustment_set_value
    qui est là pour ça.
    Ok merci. Les choses s'éclaircissent encore un peu plus. Reste donc juste à résoudre un dernier point :

    Comme récupérer la valeur à envoyer a gtk_adjustment_set_value pour mettre la position de la scrollbar tout en bas ? C'était l'idée de upper (et ca semblait marcher, même si je comprends votre réponse). Mettre une constante ne marche pas tout le temps, par exemple si la fenêtre est redimensionnée par l'utilisateur. Il faut bien argumenter ce que retourne gtk_scrolled_window_get_vadjustment. Mais comment ?

    Encore merci pour toute aide sur ce point !

    Eric.

  10. #10
    Membre régulier
    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
    Points : 100
    Points
    100
    Par défaut
    bonsoir,

    Lorsque des champs sont privés, il y a généralement des fonctions fournies par le programme pour y accéder en lecture/écriture. (get/set)

    https://developer.gnome.org/gtk3/sta...djustment.html

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gdouble upper = gtk_adjustment_get_upper (verticalAdjust);
    Ca devrait résoudre ton problème.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut
    Je lis dans la description de GtkScrolledWindow
    the "value" field represents the position of the scrollbar, which must be between the "lower" field and "upper - page_size." The "page_size" field represents the size of the visible scrollable area.
    Donc il faut non seulement mettre le positionnement après le gtk_widget_show_all(pWindow);
    mais écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     gtk_adjustment_set_value (verticalAdjust, verticalAdjust->upper - verticalAdjust->page_size);
    Remarque: dans GTK2 la structure des GtkAdjustment n'est pas privée et en imprimant les valeurs impliquées, on comprend mieux ce qui se passe.

    Par contre, dans suite(), si tu retranche le page_size, le dernier label ajouté n'est pas rendu visible, peut être à cause de l'ordre dans lequel sont effectués le callback et la négociation de la taille pour la scrolled window car si on appuie plusieurs fois sur le bouton, l'avant dernier label rajouté apparaît.
    Chez moi, en ne mettant pas le page_size dans suite(), ça marche comme espéré, mais ce n'est pas très orthodoxe.
    GraceGTK: a plotting tool at https://sourceforge.net/projects/gracegtk

  12. #12
    Membre régulier
    Homme Profil pro
    chercheur
    Inscrit en
    Décembre 2012
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : chercheur

    Informations forums :
    Inscription : Décembre 2012
    Messages : 195
    Points : 84
    Points
    84
    Par défaut
    Ok, effectivement, il faut rajouter "- verticalAdjust->page_size". Ca m'etonnait en fait que l'on ne puisse pas récupérer les éléments de la struct GtkAdjustment.

    Et effectivement, il ne faut pas argumenter verticalAdjust->page_size dans la fonction callback. Et - même si ca marche à présent effectivement - ca reste tout de même très mystérieux..

    Merci en tout cas pour l'aide.

    Cordialement,

    Eric.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 15/09/2014, 12h12
  2. SQL dynamique dans une procédure stockée
    Par Amnesiak dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 15/07/2005, 15h17
  3. variable dynamique dans une fonction javascript
    Par Shivaneth dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 20/04/2005, 15h58
  4. [jsp] include dynamique dans une jsp
    Par petitelulu dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 04/03/2005, 07h59
  5. Réponses: 6
    Dernier message: 24/09/2004, 13h10

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