Qt在布局中安排项目

问题描述 投票:0回答:3

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

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

c++ qt user-interface qlayout
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());
}

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


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

这样拉伸会将所有按钮推到左侧

© www.soinside.com 2019 - 2024. All rights reserved.