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 :

Problème de taille d'un QTreeWidget contenant un QTableWidget


Sujet :

Qt

  1. #1
    Membre averti
    Avatar de DaveShot
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    238
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2008
    Messages : 238
    Points : 384
    Points
    384
    Par défaut Problème de taille d'un QTreeWidget contenant un QTableWidget
    Bonjour,

    Je créé un QTreeWidget contenant un QTableWidget. Dans le cas ou le contenu d'une cellule de la table est sur plusieurs lignes, lorsque je déplie la première fois le niveau contenant cette table, la hauteur de celle-ci est mal calculée, car elle ne prend pas en compte la largeur des colonnes définis dans le resizeEvent. La hauteur de la table est donc trop grande. Alors que les fois suivantes, cette hauteur est bien calculée.
    J'ai réimplémenté sizeHint et minimumSizeHint pour recalculer cette hauteur, mais la première fois la méthode rowHeight est calculée en prenant en compte une largeur de 100 pixels (taille par défaut d'un widget), et ensuite la bonne largeur de la table est prise en compte, pour calculer la hauteur de la table.

    Y a t-il un moyen de calculer correctement cette hauteur à la première ouverture ?

    Merci d'avance pour votre aide.
    - N'hésitez pas à consulter les liens vers les FAQs, les cours et tutoriels -

    Daveshot

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Bonjour,

    Tu n'aurais pas un petit projet d'exemple à rajouter en pièce-jointe ? Notamment pour le multi-ligne dans la QTableWidget, qui n'est pas trivial.

  3. #3
    Membre averti
    Avatar de DaveShot
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    238
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2008
    Messages : 238
    Points : 384
    Points
    384
    Par défaut
    Bonjour,

    voici quelques éléments supplémentaires pour enrichir la description de mon problème :

    Le constructeur de ma table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    MyTableWidget::MyTableWidget ( QWidget* parent )
        : QTableWidget ( parent )
    {
        setWordWrap ( true );
     
        setFrameShape ( QFrame::NoFrame );
        setSelectionMode ( QAbstractItemView::SingleSelection );
        setSelectionBehavior ( QAbstractItemView::SelectRows );
        setEditTriggers ( QAbstractItemView::NoEditTriggers );
     
        connect ( this, SIGNAL ( doubleClicked ( const QModelIndex ) ), SLOT ( onDoubleClicked ( const QModelIndex ) ) );
    }
    La redéfinition de la méthode resizeEvent pour définir la largeur de mes colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void MyTableWidget::resizeEvent ( QResizeEvent* e )
    {
        horizontalHeader()->resizeSection ( 0, e->size ().width() * 0.60 ); //la premiere colonne prend 60% de la largeur            
        horizontalHeader()->setStretchLastSection ( true );
     
        QTableWidget::resizeEvent ( e );
    }
    La redéfinition de la méthode SizeHint, pour calculer la hauteur de la Table, en récupérant la hauteur de chaque ligne :
    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
    QSize MyTableWidget::minimumSizeHint () const
    {
        QSize l_Size ( QTableView::minimumSizeHint() );
        int l_nh ( 0 );
     
        for ( int i = 0 ; i < rowCount() ; i++ ) {
            l_nh += rowHeight ( i );
        }
     
        int l_headerHeight ( 0 );
        if ( horizontalHeader()->isHidden() == false )
            l_headerHeight = horizontalHeader()->height();
        l_Size.setHeight ( l_nh + l_headerHeight + 2 * frameWidth() );
     
        return l_Size;
     
    }
     
    QSize MyTableWidget::sizeHint () const
    {
        return minimumSizeHint();
    }
    De plus, j'ai ajouté en pièces attachées, les captures d'écran correspondant à la première puis à la seconde ouverture de la table dans le tree.

    Cordialement,

    David
    Images attachées Images attachées   
    - N'hésitez pas à consulter les liens vers les FAQs, les cours et tutoriels -

    Daveshot

  4. #4
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Bonsoir,

    Je n'ai toujours pas trop d'idée pour reproduire le problème, mais l'essentiel est bien de savoir quel signal ou événement intercepter et comment y réagir.

    "Intercepter" un signal = le connecter à un slot
    Intercepter un événement = installer un filtre. Réagir après un événement intercepté = QApplication::postEvent() (je ne sais pas si c'est propre...)

    Du coup en pièce jointe voici un projet d'exemple. Pour imiter le problème, je retaille les sections verticales (= j'agrandis/diminue la hauteur d'une ligne), et on constate que l'item de l'arbre n'est pas retaillé, soit une scrollbar apparait, soit il y a du blanc dessous.
    2 lignes sont commentées dans le code, si tu les décommentes, tu verras que dans ce cas précis cela résout le problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table->viewport()->installEventFilter ( this );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool Widget::eventFilter ( QObject* o, QEvent* e )
    {
        if ( o == table->viewport() && e->type() == QEvent::Resize )
        {
            QApplication::postEvent ( ui->treeWidget, new QEvent ( QEvent::StyleChange ) );
        }
     
        return false;
    }
    Avec ceci, lorsqu'on agrandit une ligne, la taille de l'item de l'arbre suit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect ( verticalHeader(), SIGNAL ( sectionResized ( int, int, int ) ), this, SLOT ( updateSize() ) ); // constructeur de TableWidget
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void TableWidget::updateSize()
    {
        adjustSize();
    }
    Et avec ceci, lorsqu'on diminue une ligne, la taille de l'item de l'arbre suit.

    Je pense qu'il y a moyen de faire plus propre quand même...
    Si ça ne t'aide pas, est-ce que tu peux compléter le projet d'exemple avec un delegate de façon à reproduire ton problème plus exactement ?
    Fichiers attachés Fichiers attachés

  5. #5
    Membre averti
    Avatar de DaveShot
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2008
    Messages
    238
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2008
    Messages : 238
    Points : 384
    Points
    384
    Par défaut
    Bonjour,

    merci Troudhyl, j'ai suivis tes conseils.
    Pour cela, j'ai donc ajouté la ligne suivante à mon constructeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    viewport()->installEventFilter ( this );
    ainsi que la méthode suivante pour intercepter les évènements de retaillage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    bool MyTableWidget::eventFilter ( QObject* o, QEvent* e )
    {
        if ( o == viewport() && e->type() == QEvent::Resize )
        {
            if ( parentWidget() && parentWidget()->parentWidget() && qobject_cast<QTreeView*> ( parentWidget()->parentWidget() ) )
                QApplication::postEvent ( parentWidget()->parentWidget(), new QEvent ( QEvent::StyleChange ) );
        }
     
        return false;
    }
    Dorénavant, au premier dépliage de ma table, la hauteur de celle-ci est correcte, et reste inchangée à chaque repliage/dépliage.

    David.
    - N'hésitez pas à consulter les liens vers les FAQs, les cours et tutoriels -

    Daveshot

  6. #6
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Du coup si tu le fais au niveau de la table, tu pouvais faire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    bool MyTableWidget::viewportEvent ( QEvent* e )
    {
        if ( e->type() == QEvent::Resize )
        {
            if ( parentWidget() && parentWidget()->parentWidget() && qobject_cast<QTreeView*> ( parentWidget()->parentWidget() ) )
                QApplication::postEvent ( parentWidget()->parentWidget(), new QEvent ( QEvent::StyleChange ) );
        }
     
        return QTableWidget::viewportEvent ( e );
    }

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/02/2009, 17h21
  2. Problème de taille de tableau
    Par k-nine dans le forum C
    Réponses: 6
    Dernier message: 25/09/2005, 09h16
  3. [CSS] Problème de taille de div
    Par meda dans le forum Mise en page CSS
    Réponses: 6
    Dernier message: 24/08/2005, 14h30
  4. [swing][JComboBox]Problème de taille
    Par n!co dans le forum Composants
    Réponses: 8
    Dernier message: 06/03/2004, 10h53
  5. [langage] Problème de taille de fichier à mettre dans
    Par And_the_problem_is dans le forum Langage
    Réponses: 10
    Dernier message: 13/08/2002, 09h41

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