0

在过去的几天里,我试图解决 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

感谢您阅读我的帖子,希望您知道解决方案:)

4

3 回答 3

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

在这种情况下,您还应该在调整大小时更新自定义尺寸,因为布局将尝试恢复默认比例。

于 2014-01-20T12:07:21.440 回答
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 );
}
于 2014-01-20T10:44:24.517 回答
0

我不知道这是不是一个坏主意。

你可以让你的 firstRowLayout 全局,然后在你的 decrement() 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);
}

这样拉伸会将你所有的按钮推到左边

于 2018-09-08T07:56:54.527 回答