Qt расположение элементов в макете

Последние пару дней я пытаюсь решить конкретную проблему с системой Qt Layout. Я постараюсь обобщить это:
У меня есть виджет с двумя рядами. В первом ряду находятся кнопки дерева (или любые другие элементы управления). Их расположение показано на картинке:
введите описание изображения здесь

Центральная кнопка занимает все доступное дополнительное пространство (и расширяется по мере того, как виджет увеличивает свой размер). Дело в том, что я хочу программно изменить размер центрального виджета (кнопки) и сохранить макет. С моей текущей реализацией, когда я изменяю размер центральной кнопки, вот что происходит:

введите описание изображения здесь

Я хочу, чтобы правая кнопка была выровнена справа от центральной кнопки (без дополнительного места). Теперь, когда я изменяю размер виджета, он возвращается в положение 1 (центр занимает все дополнительное пространство), но это не тот эффект, который мне нужен.

Вот моя текущая реализация:

#include "Widget_Old.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDebug>

WidgetOld::WidgetOld(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout* mainLayout = new QVBoxLayout( this );

QWidget* firstRowWidget = new QWidget( this );

QPushButton* left   = new QPushButton;
left->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
left->setText( "left" );

m_center = new QPushButton;
m_center->setText( "centerr");
m_center->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );

QPushButton* right  = new QPushButton;
right->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
right->setText( "right" );

QHBoxLayout* firstRowLayout = new QHBoxLayout( firstRowWidget );

firstRowLayout->addWidget( left );
firstRowLayout->addWidget( m_center );
firstRowLayout->addWidget( right );

QHBoxLayout* secondRowLayout = new QHBoxLayout;
QPushButton* button = new QPushButton( "resize" );
connect( button, SIGNAL(clicked()), SLOT(decrement()) );
secondRowLayout->addWidget( button );

mainLayout->addWidget( firstRowWidget  );
mainLayout->addLayout( secondRowLayout );
}

WidgetOld::~WidgetOld()
{
}void WidgetOld::decrement()
{
qDebug() << "Changing width from " << m_center->width() << " to " << m_center->width()/2;
m_center->resize( m_center->width()/2, m_center->height() );
}

Заметки:

Я пытался выровнять центр и правый виджет Qt :: AlignLeft, но безрезультатно. На самом деле, когда
выравнивая виджет слева в макете, он пытается получить минимальный размер, который нарушает расширяющуюся функциональность 🙁

Я поделился своим кодом, если какая-либо ссылка нужна:
https://drive.google.com/file/d/0B-mc4aKkzWlxTWdNNmpuQ0ptQ3M/edit?usp=sharing

Спасибо за чтение моего поста, надеюсь, вы знаете решение 🙂

0

Решение

Вы должны установить максимальный размер вашего центрального виджета. Чтобы адаптировать нужный виджет, установите для его политики размера значение MinimumExpanding при изменении размера центрального:

void WidgetOld::decrement ()
{
qDebug() << "Changing width from " << m_center->width() << " to " << m_center->width()/2;
m_center->setMaximumWidth (m_center->width()/2);
m_right->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
}

альтернативно, если вы измените размер центрального виджета вручную (что устарело, как отмечалось выше), вы также должны обновить геометрию правого виджета вручную. Тогда ваш decrement метод должен выглядеть так

void WidgetOld::decrement ()
{
qDebug() << "Changing width from " << m_center->width() << " to " << m_center->width()/2;
m_center->resize( m_center->width()/2, m_center->height() );
int rightPosX = m_center->pos().x() + m_center->width() + m_firstRowLayout->spacing ();
int rightWidth = centralWidget()->pos().x() + centralWidget()->width() - m_mainLayout->margin() - rightPosX;
m_right->setGeometry (rightPosX, m_right->pos().y(), rightWidth, m_right->height());
}

В этом случае вам также следует обновить ваши собственные размеры при изменении размера, так как макет будет пытаться восстановить пропорции по умолчанию.

0

Другие решения

когда вы используете макеты, вы перекладываете ответственность за управление размером на макет, поэтому НИКОГДА не следует изменять размеры элементов вручную, когда они находятся в макете.

попробуй это:

WidgetOld::WidgetOld(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout* mainLayout = new QVBoxLayout( this );

QWidget* firstRowWidget = new QWidget( this );

QPushButton* left   = new QPushButton;
left->setText( "left" );
left->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );

m_center = new QPushButton;
m_center->setText( "centerr");
m_center->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );

QPushButton* right  = new QPushButton;
right->setText( "right" );
right->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );

QHBoxLayout* firstRowLayout = new QHBoxLayout( firstRowWidget );

firstRowLayout->addWidget( left );
firstRowLayout->addStretch();
firstRowLayout->addWidget( m_center );
firstRowLayout->addStretch();
firstRowLayout->addWidget( right );

QHBoxLayout* secondRowLayout = new QHBoxLayout;
QPushButton* button = new QPushButton( "resize" );
connect( button, SIGNAL(clicked()), SLOT(decrement()) );
secondRowLayout->addWidget( button );

mainLayout->addWidget( firstRowWidget  );
mainLayout->addLayout( secondRowLayout );
}
0

Я не знаю, плохая ли это идея.

Не могли бы вы сделать свой firstRowLayout глобальным, а затем динамически добавить растяжку к макету в конце в вашей функции SLOT декремента ()?

void WidgetOld::decrement(){
qDebug() << "Changing width from " << m_center->width() << " to " << m_center->width()/2;
m_center->resize( m_center->width()/2, m_center->height() );
firstRowLayout->addStretch(1);
}

таким образом растяжка будет нажимать все ваши кнопки влево

0
По вопросам рекламы [email protected]