سؤال

I am creating a widget which contains a chess table and six buttons which are displayed in 2 rows beneath the chess table. The button rows are wider than the chess table. Chess table and buttons are in a QGridLayout. Chess table has its own sizeHint calculated from the size of the squares.

After some operations I delete the buttons and resize the widget that contains everything to its sizeHint (resize(sizeHint())). The widget resizes properly in the vertical direction but in the horizontal direction it remains as wide as if the button rows were there. What is the problem ?

If I construct the widget only with the chess table the layout sizes the widget properly.

I am adding the code:

In the constructor of the window:

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

formLayout = new QGridLayout;

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

setLayout(formLayout);

In the function that adds the buttons:

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);

In the function that deletes everything besides the chess table:

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());

The sizeHint for the chess table is calculated as:

return QSize(m_rowNo*spacing, m_colNo*spacing)+QSize(31,31);
هل كانت مفيدة؟

المحلول

  1. You must activate() the layout before for its sizeHint(), and subsequently the widget's sizeHint(), to be updated immediately after modifying the laid out widgets.

  2. The calls to layout->removeWidget() are redundant. Simply delete the unneeded widgets. Qt handles all memory allocation in QWidget hierarchies. Deleting a QWidget without telling anyone on the Qt end of things is safe. There are sane exceptions of course: you can't delete a widget whose method is somewhere on the call stack, for example.

  3. If you don't want to bother with calling resize(), you can set the appropriate size constraint on the widget's layout. For example:

    layout->setSizeConstraint(QLayout::SetFixedSize);

    This ensures that the widget will size itself only large enough to fit the contents per the sizeHint().

Taking points 1 and 2 into account, the function that 'deletes everything besides the chess table' might look like the below:

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

    formLayout->activate();
    resize(sizeHint());
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top