Сохранить виджеты в таблице квадратом и центрировать их в окне
Я хочу добиться поведения QGridLayout, при котором виджеты, находящиеся внутри, пропорционально увеличивались при увеличении окна, но, сохраняли квадратный размер и местоположение QGridLayout оставалось в центре. Приведу пример того, что я пытаюсь сделать:

Я пытался переопределить heightForWidth:
#include <QtWidgets>
class TestLbl : public QLabel
{
Q_OBJECT
public:
TestLbl(QWidget* obj = nullptr): QLabel(obj){}
TestLbl(QString ttl, QWidget* obj = nullptr): QLabel(ttl, obj){}
bool hasHeightForWidth( )const override
{
return true;
}
int heightForWidth( int w )const override
{
return w;
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
QVBoxLayout l;
l.addWidget(new QLabel("test"));
l.addStretch();
QGridLayout layout;
for( int i =0 ; i < 4; i++ )
{
layout.setRowStretch( i, 1);
for ( int j = 0; j < 4; j++)
{
layout.setColumnStretch( j, 1 );
TestLbl *temp = new TestLbl( "1" );
temp->setFrameStyle(QFrame::Box | QFrame::Plain);
layout.addWidget( temp, i, j, 1, 1 );
}
}
l.addLayout(&layout);
l.addStretch();
QHBoxLayout bl;
bl.addWidget(new QLabel("test"));
bl.addStretch();
bl.addWidget(new QLabel("test"));
l.addLayout(&bl);
widget.setLayout( &l );
widget.show();
a.exec();
return 0;
}
Но это даёт результат, при котором окно не может свободно менять свой размер, только по диагонали, причем при фуллскрине квадратные элементы вовсе теряются. Главный вопрос: как добиться результата, при котором окно может свободно менять свой размер, QGridLayout центрируется по своей позиции, элементы внутри пропорционально увеличиваются/уменьшаются, при этом оставаясь квадратом? P.S.: я знаю, что в примере много ошибок (объекты на стеке и тд). Это просто пример
Ответы (1 шт):
Желаемого поведения можно добиться жонглируя (кроме heightForWidth) еще и sizeHint, minimalSize, maximalSize... Но проще сразу написать свою процедуру упорядочения элементов на столе (свой Layout). Например, растягивание единственного дочернего элемента в виде максимального квадрата:
#include <QHBoxLayout>
class CentralSquareLayout : public QHBoxLayout
{
public:
using QHBoxLayout::QHBoxLayout;
QSize sizeHint () const { return squareSizeMax( QHBoxLayout::sizeHint () ); }
QSize minimumSize () const { return squareSizeMax( QHBoxLayout::minimumSize() ); }
QSize maximumSize () const { return squareSizeMin( QHBoxLayout::maximumSize() ); }
void setGeometry(const QRect &rect)
{
QRect child_rect;
child_rect.setSize(squareSizeMin(rect.size()));
child_rect.moveCenter(rect.center());
for( int i=0; i<count(); ++i)
itemAt(i)->setGeometry(child_rect);
}
private:
static QSize squareSizeMax( QSize s )
{
auto m = std::max(s.height(), s.width());
return QSize( m, m );
}
static QSize squareSizeMin( QSize s )
{
auto m = std::min(s.height(), s.width());
return QSize( m, m );
}
};
Использование:
QVBoxLayout l;
l.addWidget(new QLabel("test"));
l.addStretch(1);
CentralSquareLayout square;
QGridLayout layout;
for( int i =0 ; i < 4; i++ )
{
...
}
square.addItem(&layout);
l.addLayout(&square, 1); // второй параметр - насколько нужно растягивать центральный квадрат в сравнении с растягиванием пробелов сверху и снизу
l.addStretch(1);
....