在过去的几天里,我试图解决Qt布局系统的特定问题。我将尝试概括它:我有一个有两行的小部件。在第一行有树按钮(或任何其他控件)。它们的布局如图所示:
中心按钮占用了所有可用的额外空间(并且随着小部件增加其大小而扩展)。问题是我想以编程方式想要调整中心小部件(按钮)的大小并保持布局。通过我当前的实现,当我调整中心按钮的大小时,会发生以下情况:
我希望右按钮在中心按钮的右侧对齐(没有额外的空间)。现在,当我调整小部件的大小时,它将返回到位置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
感谢您阅读我的帖子,希望您知道解决方案:)
您必须设置中央窗口小部件的最大大小。要调整正确的窗口小部件,请在调整中心窗口大小时将其大小策略设置为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());
}
在这种情况下,您还应该在调整大小时更新自定义大小,因为布局将尝试恢复默认比例。
当您使用布局时,您将管理大小的责任移到布局上,因此在布局时不应手动调整项目的大小。
试试这个:
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 );
}
我不知道这是不是一个坏主意。
你可以让你的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);
}
这样拉伸会将所有按钮推到左侧