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

Qt Discussion :

QScrollArea contenant une FlowLayout


Sujet :

Qt

  1. #1
    Membre averti Avatar de Chatbour
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 431
    Points : 305
    Points
    305
    Par défaut QScrollArea contenant une FlowLayout
    Bonjour à tous,

    En utilisant la classe FlowLayout (fournie ici), j'essaie de créer un QGroupBox contenant une layout contenant 100 objets QPushButton.

    Je veux utiliser un object QScrollArea qui contient la layout, voici mon 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
    QWidget widget;
     
    FlowLayout *flayout = new FlowLayout();
    for (int i = 0; i < 100; ++i) {
    	QPushButton *button = new QPushButton("Bouton ");
    	flayout->addWidget(button);
    }
     
    QScrollArea *scroll = new QScrollArea();
    scroll->setLayout(flayout);
     
    QGridLayout *grid = new QGridLayout();
    grid->addWidget(scroll);
     
    QGroupBox *group = new QGroupBox("Group");
    group->setLayout(grid);
     
    QGridLayout *layout = new QGridLayout();
    layout->addWidget(group);
     
    widget.setLayout(layout);
    widget.resize(300, 200);
    widget.show();
    le problème c'est que le widget QScrollArea n'est jamais affiché. Quelqu'un a-t-il l'explication ? Merci d'avance.

    Je vous remercie,
    Chatbour.

  2. #2
    Membre à l'essai
    Profil pro
    dev
    Inscrit en
    Juillet 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Juillet 2009
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    J'ai moi même besoin d'utilisé un FlowLayout en ce moment.
    J'ai repris le code de l'exemple fournit pat Qt comme toi.

    Pour ton problème, j'ai été direct modifier le code de l'exemple dans le fichier window.cpp ( dans examples/layouts/flowlayout ) et y en intégrant ton bout de code (modifier légèrement par mes soins).

    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
    Window::Window()
    {
        FlowLayout *flowLayout = new FlowLayout;
     
        flowLayout->addWidget(new QPushButton(tr("Short")));
        flowLayout->addWidget(new QPushButton(tr("Longer")));
        flowLayout->addWidget(new QPushButton(tr("Different text")));
        flowLayout->addWidget(new QPushButton(tr("More text")));
        flowLayout->addWidget(new QPushButton(tr("Even longer button text")));
     //   setLayout(flowLayout);
     
        setWindowTitle(tr("Flow Layout"));
     
        QScrollArea *scroll     ;
        QGroupBox   *group      ;
        QHBoxLayout *l_layout   ;
        QHBoxLayout *layout_gen ;
     
        scroll = new QScrollArea ;
        scroll->setLayout( flowLayout ) ;
     
        group = new QGroupBox( "Group" ) ;
        l_layout = new QHBoxLayout( group ) ;
        l_layout->addWidget( scroll ) ;
     
        layout_gen = new QHBoxLayout( this ) ;
        layout_gen->addWidget( group ) ;
     
        this->resize( 300, 200 ) ;
    }
    J'ai bien les boutons qui s'affichent dans le groupe box dont les contours sont dessinées !

    Mais quand on diminue manuellement en tirant le coin les boutons disparaissent sans que la scrollbare vertical n'apparaissent !

    Est-ce ton problème. car il semble que nous en ayons un similaire.

  3. #3
    Membre à l'essai
    Profil pro
    dev
    Inscrit en
    Juillet 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Juillet 2009
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    Il semble qu'il ne faille pas appliquer un layout au QScrollArea mais utiliser la fonction setWidget, en n'oubliant pas d'indiquer que le widget puisse se redimensionner en utilisant la fonction setWidgetResizable ; j'ai modifier le code en conséquence.

    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
    Window::Window()
    {
        FlowLayout *flowLayout = new FlowLayout;
        flowLayout->addWidget(new QPushButton(tr("Short")));
        flowLayout->addWidget(new QPushButton(tr("Longer")));
        flowLayout->addWidget(new QPushButton(tr("Different text")));
        flowLayout->addWidget(new QPushButton(tr("More text")));
        flowLayout->addWidget(new QPushButton(tr("Even longer button text")));
        //setLayout(flowLayout);
     
        setWindowTitle(tr("Flow Layout"));
     
        QScrollArea *scroll     ;
        QGroupBox   *group      ;
        QHBoxLayout *l_layout   ;
        QHBoxLayout *layout_gen ;
        QWidget     *widget     ;
     
        widget = new QWidget ;
        widget->setLayout( flowLayout ) ;
     
        scroll = new QScrollArea ;
        //scroll->setLayout( flowLayout ) ;
        scroll->setWidget( widget ) ;
        scroll->setWidgetResizable( true ) ;
     
        group = new QGroupBox( "Group" ) ;
        l_layout = new QHBoxLayout( group ) ;
        l_layout->addWidget( scroll ) ;
     
        layout_gen = new QHBoxLayout( this ) ;
        layout_gen->addWidget( group ) ;
     
        this->resize( 300, 200 ) ;
    }
    Les scrollbars apparaissent et les boutons se déploient horizontalement !!

  4. #4
    Membre à l'essai
    Profil pro
    dev
    Inscrit en
    Juillet 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Juillet 2009
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    Bon ! j'espère que ce post n'était pas trop enterré et que ton problème a été ou sera résolu maintenant.

    Moi mon soucis est de forcer dynamiquement un minimum height au widget manageant le flowLayout en fonction de son width.

    Comme tu as pu le remarquer dans l'exemple fournit pas Qt, lorsque qu'on resize le widget, en jouant avec le coin, il arrivent que les boutons disparaissent car la fonction minimunSize() surchargée dans la classe FlowLayout retourne une taille "expanded" à partir des taille minimum des items qu'il gère.

    J'ai essayé de rajouter une ligne de code dans cette fonction pour forcer le height.
    Le remède semble pire que le mal car cela n'est pas dynamique.
    la fonction n'est en effet appelée que quelque fois au début de l'affichage et non à chaque redimensionnement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    QSize FlowLayout::minimumSize() const
    {
        QSize size;
        QLayoutItem *item;
        foreach (item, itemList)
            size = size.expandedTo(item->minimumSize());
     
        size.rheight() = this->heightForWidth( size.width() ) ; //code ajouté mais BOF !!
     
        size += QSize(2*margin(), 2*margin());
        return size;
    }
    Voila ou j'en suis !! si je n'arrive pas à gérer dynamiquement le heigth, j'aurais toujours la possibilité d'utiliser la solution avec la QScrollArea (merci à toi du coup pour l'astuce).

    Si quelqu'un à une solution pour mon soucis ... grand merci !

  5. #5
    Membre à l'essai
    Profil pro
    dev
    Inscrit en
    Juillet 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Juillet 2009
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    J'ai modifié encore un peu le code de windows.cpp de l'exemple flowLayout, afin d'avoir une espèce de minimun height dynamique. J'ai viré la QScrollArea car je n'ai pas réussi à lui faire prendre en compte le minimumSize du flowLayout du widget ( passé par setWidget).

    Cette fois j'ai juste utilisé un QGroupeBox et surtout surchargé la fonction resizeEvent pour utilisé ma fonction force_old_size.

    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
     
    Window::Window()
    {
        FlowLayout *flowLayout = new FlowLayout;
     
        flowLayout->addWidget(new QPushButton(tr("Short")));
        flowLayout->addWidget(new QPushButton(tr("Longer")));
        flowLayout->addWidget(new QPushButton(tr("Different text")));
        flowLayout->addWidget(new QPushButton(tr("More text")));
        flowLayout->addWidget(new QPushButton(tr("Even longer button text")));
     
        setWindowTitle(tr("Flow Layout"));
     
        /* nécessaire si l'objet gère directement le flowLayout pour que le minimumSize soit pris en compte */
        flowLayout->setSizeConstraint( QLayout::SetMinimumSize ) ;
     
        // Ajout des boutons dans un QGroupBox
        QGroupBox *gb = new QGroupBox ;
        gb->setLayout( flowLayout ) ;
     
        QHBoxLayout *lay = new QHBoxLayout( this ) ;
        lay->addWidget( gb ) ;
        /* nécessaire pour que le minimumSize soit pris en compte */
        lay->setSizeConstraint( QLayout::SetMinimumSize ) ;
    }
     
    void Window::resizeEvent( QResizeEvent *event )
    {
    bool breaking ;
     
    /* Si le layout de l'objet est un FlowLayout (cas : pas de QGroupBox utilisé dans le constructeur) */
    breaking = this->force_old_size( this, event->oldSize() ) ;
     
    if ( breaking == false )
    {
     
        foreach ( QObject *obj, this->children() )
        {
        breaking = this->force_old_size( qobject_cast<QWidget *>( obj ), event->oldSize() ) ;
     
    	if ( breaking == true )
    	break ;
        }
    }
     
    if ( breaking == false )
    QWidget::resizeEvent( event ) ;
     
    }
     
    bool Window::force_old_size( QWidget *widget, QSize old_size )
    {
    bool retour ;
     
    retour = false ;
     
    if ( widget != 0 && qobject_cast<FlowLayout *>( widget->layout() ) != 0 )
    {
        if ( widget->height() < widget->heightForWidth( widget->width() ) )
        {
        this->resize( old_size ) ;
     
        retour  = true ;
        }
    }
     
    return retour ;
    }
    Cela marchote !
    Quand on resize et que le height effectif est plus petit que le height minimum retourné par le heightForWidth, le widget Window retrouvera sa taille d'avant le resize mais seulement après qu'on ai relâché la souris !! Effet étrange et moyen, qui ne simule pas vraiment un mimumSize dynamique!

    Je vois plusieurs problème :
    - utilisation intempestive du qobject_cast (j'ai du ajouter la macro Q_OBJECT à FlowLayout)
    - Cela marchote, c'est moche
    - Si un développeur tiers utilise l'objet Window et le met dans une QDialog (via un QGridLayout par ex ), on retrouve le problème de disparition des boutons, et s'il oublie d'utiliser QLayout::setSizeConstraint( QLayout::SetMinimumSize ), le minimumSize du FlowLayout n'est plus pris en compte (normale en fait ) !

    Je poursuis mes investigations sur l'utilsation de layout ayant un height dépendant du width.
    Si vous avez des éclaircissements je suis prenneur

    Bonne soirée A+

Discussions similaires

  1. Trouver un fichier contenant une chaine ?
    Par narmataru dans le forum Linux
    Réponses: 2
    Dernier message: 29/04/2004, 11h49
  2. [ADO] requete contenant une variable ?
    Par kam dans le forum MFC
    Réponses: 9
    Dernier message: 28/04/2004, 12h08
  3. Réponses: 3
    Dernier message: 28/10/2003, 15h26
  4. VARCHAR contenant une quote '
    Par tonyskn dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/05/2003, 20h21
  5. Fichier ressource contenant une icône
    Par k_boy dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 26/09/2002, 21h59

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