2012-06-18 3 views
2

Je crée un widget qui contient une table d'échecs et six boutons qui sont affichés sur 2 lignes sous la table d'échecs. Les rangées de boutons sont plus larges que la table d'échecs. La table et les boutons d'échecs sont dans un QGridLayout. La table d'échecs a sa taille sizeHint calculée à partir de la taille des carrés. Après quelques opérations, je supprime les boutons et redimensionne le widget qui contient tout à sa taille sizeHint (resize(sizeHint())). Le widget se redimensionne correctement dans la direction verticale mais dans la direction horizontale il reste aussi large que si les rangées de boutons étaient là. Quel est le problème ?layout sizeHint qwidget

Si je construis le widget uniquement avec la table d'échecs, la mise en page dimensionne correctement le widget.

J'ajoute le code:

Dans le constructeur de la fenêtre:

renderArea = new RenderArea(m_row,m_col,m_grid); 

formLayout = new QGridLayout; 

formLayout->addWidget(renderArea,0,0,1,3); 

setLayout(formLayout); 

Dans la fonction qui ajoute les boutons:

addPlaneButton = new QPushButton(tr("Add plane")); 
cancelButton = new QPushButton(tr("Cancel operation")); 
movePlaneButton = new QPushButton(tr("Move plane")); 
deletePlaneButton = new QPushButton(tr("Delete plane")); 
rotatePlaneButton = new QPushButton(tr("Rotate plane")); 
doneButton = new QPushButton(tr("Done")); 
doneButton->setEnabled(false); 

infoLabel = new QLabel(tr("Welcome to the plane editor")); 
statusLabel = new QLabel(); 

formLayout->addWidget(statusLabel,1,0,1,3); 
formLayout->addWidget(infoLabel,2,0,1,3); 
formLayout->addWidget(addPlaneButton,3,0); 
formLayout->addWidget(movePlaneButton,3,1); 
formLayout->addWidget(deletePlaneButton,3,2); 
formLayout->addWidget(rotatePlaneButton,4,0); 
formLayout->addWidget(cancelButton,4,1); 
formLayout->addWidget(doneButton, 4,2); 

Dans la fonction qui supprime tout en plus la table d'échecs:

formLayout->removeWidget(addPlaneButton); 
formLayout->removeWidget(cancelButton); 
formLayout->removeWidget(movePlaneButton); 
formLayout->removeWidget(deletePlaneButton); 
formLayout->removeWidget(rotatePlaneButton); 
formLayout->removeWidget(doneButton); 
formLayout->removeWidget(infoLabel); 
formLayout->removeWidget(statusLabel); 


delete addPlaneButton; 
delete cancelButton; 
delete movePlaneButton; 
delete deletePlaneButton; 
delete rotatePlaneButton; 
delete doneButton; 


delete infoLabel; 
delete statusLabel; 

resize(sizeHint()); 

Le sizeHint pour la table d'échecs est calculé comme suit:

return QSize(m_rowNo*spacing, m_colNo*spacing)+QSize(31,31); 
+0

Ce n'est pas vraiment assez d'informations. – Robert

+0

J'ai mis à jour ma question avec du code. – Cristi

Répondre

4
  1. Vous devez activate() la mise en page avant pour son sizeHint(), puis être mis à jour immédiatement sizeHint() de widget, après avoir modifié les énoncés des widgets.

  2. Les appels à layout->removeWidget() sont redondants. Simplement delete les widgets inutiles. Qt gère toutes les allocations de mémoire dans les hiérarchies QWidget. Suppression d'un QWidget sans en parler à personne sur l'extrémité Qt est sûr. Il y a bien sûr des exceptions saines: vous ne pouvez pas supprimer un widget dont la méthode est quelque part dans la pile des appels, par exemple.

  3. Si vous ne voulez pas vous préoccuper d'appeler resize(), vous pouvez définir la contrainte de taille appropriée sur la disposition du widget. Par exemple:

    layout->setSizeConstraint(QLayout::SetFixedSize);

    Cela garantit que le widget taille lui-même juste assez grande pour adapter le contenu par la sizeHint().

Prendre les points 1 et 2 en compte, la fonction « supprime tout en plus de la table d'échecs » pourrait ressembler le ci-dessous:

void removeButtons() { 
    delete addPlaneButton; 
    delete cancelButton; 
    delete movePlaneButton; 
    delete deletePlaneButton; 
    delete rotatePlaneButton; 
    delete doneButton; 
    delete infoLabel; 
    delete statusLabel; 

    formLayout->activate(); 
    resize(sizeHint()); 
} 
+0

Selon la documentation de 'QLayout' pour' activate() ':" Vous ne devriez généralement pas avoir besoin de l'appeler car il est automatiquement appelé au moment le plus approprié. " Je suggère d'utiliser 'QWidget :: updateGeometry()' pour notifier Qt des changements de disposition. –

+0

Merci Kuba Ober. J'ai ajouté la fonction activate() et le redimensionnement a fonctionné corectly. updateGeometry() ne fait pas le travail. – Cristi

+0

Johannes: 'updateGeometry()' serait une chose redondante à appeler. Il notifie simplement le système de mise en page que les choses ont changé. Il n'est pas nécessaire de le notifier, car la suppression des widgets déjà installés le fait déjà. Je pense que la seule bonne raison d'appeler 'updateGeometry()' est quand vous mettez à jour 'sizeHint()' ou les tailles minimum/maximum dans un widget. Un appel à 'activate()' force le système de mise en page à recalculer les mises en page là et maintenant. Normalement, il aurait été reporté à la boucle d'événements - après l'appel 'resize (....)' qui utilise ensuite 'sizeHint()' de l'ancien état des mises en page. Qt docs sont parfois faux. –