Précédent   Forum du club des développeurs et IT Pro > C et C++ > Bibliothèques > Qt
Qt Forum d'entraide technique sur la bibliothèque Qt. Avant de poster -> F.A.Q Qt
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 13/09/2012, 10h25   #1
DaveShot
Membre éclairé
 
Avatar de DaveShot
 
Homme David Shot
Ingénieur développement logiciels
Inscription : août 2008
Messages : 206
Détails du profil
Informations personnelles :
Nom : Homme David Shot
Localisation : France, Haute Garonne (Midi Pyrénées)

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

Informations forums :
Inscription : août 2008
Messages : 206
Points : 324
Points : 324
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.
DaveShot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2012, 01h56   #2
Troudhyl
Modérateur
 
Homme
Ingénieur développement logiciels
Inscription : mai 2009
Messages : 967
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France

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

Informations forums :
Inscription : mai 2009
Messages : 967
Points : 1 693
Points : 1 693
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.
Troudhyl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2012, 10h29   #3
DaveShot
Membre éclairé
 
Avatar de DaveShot
 
Homme David Shot
Ingénieur développement logiciels
Inscription : août 2008
Messages : 206
Détails du profil
Informations personnelles :
Nom : Homme David Shot
Localisation : France, Haute Garonne (Midi Pyrénées)

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

Informations forums :
Inscription : août 2008
Messages : 206
Points : 324
Points : 324
Bonjour,

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

Le constructeur de ma table :
Code :
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 :
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 :
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
Type de fichier : jpg Table_premier_ouverture.JPG (29,1 Ko, 6 affichages)
Type de fichier : jpg Table_second_ouverture.JPG (24,2 Ko, 5 affichages)
DaveShot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/09/2012, 23h23   #4
Troudhyl
Modérateur
 
Homme
Ingénieur développement logiciels
Inscription : mai 2009
Messages : 967
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France

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

Informations forums :
Inscription : mai 2009
Messages : 967
Points : 1 693
Points : 1 693
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 :
table->viewport()->installEventFilter ( this );
Code :
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 :
connect ( verticalHeader(), SIGNAL ( sectionResized ( int, int, int ) ), this, SLOT ( updateSize() ) ); // constructeur de TableWidget
Code :
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
Type de fichier : zip TreeTable.zip (3,3 Ko, 2 affichages)
Troudhyl est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 10/12/2012, 16h33   #5
DaveShot
Membre éclairé
 
Avatar de DaveShot
 
Homme David Shot
Ingénieur développement logiciels
Inscription : août 2008
Messages : 206
Détails du profil
Informations personnelles :
Nom : Homme David Shot
Localisation : France, Haute Garonne (Midi Pyrénées)

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

Informations forums :
Inscription : août 2008
Messages : 206
Points : 324
Points : 324
Bonjour,

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

Code :
viewport()->installEventFilter ( this );
ainsi que la méthode suivante pour intercepter les évènements de retaillage :

Code :
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.
DaveShot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 18h38   #6
Troudhyl
Modérateur
 
Homme
Ingénieur développement logiciels
Inscription : mai 2009
Messages : 967
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France

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

Informations forums :
Inscription : mai 2009
Messages : 967
Points : 1 693
Points : 1 693
Du coup si tu le fais au niveau de la table, tu pouvais faire directement :

Code :
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 );
}
Troudhyl est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 01h28.


 
 
 
 
Partenaires

Hébergement Web