C++ 内容动态变化的QScrollArea
我有一个QScrollArea,里面有一些按钮,如图所示。 布局的理念是: 1.当按钮太宽时,应使用左右按钮滚动按钮 2.滚动区域中的按钮数量可以动态更改 3.应使用任何可用空间尽可能扩大滚动区域。如果不存在此类空间,则应使用导航按钮进行滚动 在我当前的实现中,当我增加按钮时,我有: 但右侧有可用空间,因此应如下所示: 例如,如果我再次增加到10,那么滚动条应该出现(因为布局是由小部件控制的) 我想知道除了手动调整小部件的大小之外,是否还有其他方法(因为ui可以转换,按钮可以更改大小),但实际设计更复杂:( 下面是我对ScrollAreaTest小部件的实现:C++ 内容动态变化的QScrollArea,c++,qt,desktop-application,qscrollarea,qlayout,C++,Qt,Desktop Application,Qscrollarea,Qlayout,我有一个QScrollArea,里面有一些按钮,如图所示。 布局的理念是: 1.当按钮太宽时,应使用左右按钮滚动按钮 2.滚动区域中的按钮数量可以动态更改 3.应使用任何可用空间尽可能扩大滚动区域。如果不存在此类空间,则应使用导航按钮进行滚动 在我当前的实现中,当我增加按钮时,我有: 但右侧有可用空间,因此应如下所示: 例如,如果我再次增加到10,那么滚动条应该出现(因为布局是由小部件控制的) 我想知道除了手动调整小部件的大小之外,是否还有其他方法(因为ui可以转换,按钮可以更改大小),但
#include "MainWidget.h"
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
#include <QPushButton>
#include <QDebug>
#include "ButtonWidget.h"
#include "CheckableButtonGroup.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent),
m_scrollArea( 0 ),
m_lineEdit( 0 ),
m_buttons( 0 )
{
QVBoxLayout* mainLayout = new QVBoxLayout( this );
QWidget* firstRow = new QWidget;
QHBoxLayout* firstRowLayout = new QHBoxLayout( firstRow );
QPushButton* left = new QPushButton;
QPushButton* right = new QPushButton;
m_buttons = new CheckableButtonGroup( Qt::Horizontal );
m_buttons->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
m_buttons->setButtonsCount( 5 );
m_buttons->setStyleSheet( "border: none" );
QWidget* const buttonsContainer = new QWidget;
QHBoxLayout* const buttonsContainerLayout = new QHBoxLayout( buttonsContainer );
buttonsContainerLayout->setSpacing( 0 );
buttonsContainerLayout->setSizeConstraint( QLayout::SetMinAndMaxSize );
buttonsContainerLayout->setMargin( 0 );
buttonsContainerLayout->addWidget( m_buttons, 0, Qt::AlignLeft );
qDebug() << m_buttons->buttons()[ 0 ]->size();
m_scrollArea = new QScrollArea;
m_scrollArea->setContentsMargins( 0, 0, 0, 0 );
m_scrollArea->setWidget( buttonsContainer );
m_scrollArea->setWidgetResizable( true );
m_scrollArea->setStyleSheet( "border: 1px solid blue" );
m_scrollArea->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
firstRowLayout->addWidget( left , 0, Qt::AlignLeft );
firstRowLayout->addWidget( m_scrollArea, 1, Qt::AlignLeft );
firstRowLayout->addWidget( right , 0, Qt::AlignLeft );
m_lineEdit = new QLineEdit;
QPushButton* button = new QPushButton;
QHBoxLayout* secondRowLayout = new QHBoxLayout;
secondRowLayout->addWidget( m_lineEdit );
secondRowLayout->addWidget( button );
connect( button, SIGNAL(clicked()), SLOT(setButtonsCount()) );
mainLayout->addWidget( firstRow, 1, Qt::AlignLeft );
mainLayout->addLayout( secondRowLayout );
button->setText( "Set buttons count" );
buttonsContainer->resize( m_buttons->buttonsOptimalWidth(), buttonsContainer->height() );
m_buttons->resize( m_buttons->buttonsOptimalWidth(), m_buttons->height() );
//area->resize( 100, area->height() );
//area->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
}
MainWidget::~MainWidget()
{
}
void MainWidget::setButtonsCount()
{
m_buttons->setButtonsCount( m_lineEdit->text().toInt() );
}
#包括“MainWidget.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括“ButtonWidget.h”
#包括“CheckableButtonGroup.h”
MainWidget::MainWidget(QWidget*父项)
:QWidget(父项),
m_滚动区域(0),
m_lineEdit(0),
m_按钮(0)
{
QVBoxLayout*mainLayout=新的QVBoxLayout(此);
QWidget*第一行=新的QWidget;
QHBoxLayout*firstRowLayout=新的QHBoxLayout(第一行);
QPushButton*左=新的QPushButton;
QPushButton*右=新的QPushButton;
m_按钮=新的可检查按钮组(Qt::水平);
m_按钮->设置策略(QSizePolicy::扩展,QSizePolicy::首选);
m_按钮->设置按钮计数(5);
m_按钮->设置样式表(“边框:无”);
QWidget*const buttonsContainer=新的QWidget;
QHBoxLayout*const buttonsContainerLayout=新的QHBoxLayout(buttonsContainer);
按钮容器布局->设置间距(0);
按钮ContainerLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
按钮容器布局->设置边距(0);
buttonsContainerLayout->addWidget(m_按钮,0,Qt::AlignLeft);
qDebug()按钮()[0]->size();
m_scrollArea=新的QScrollArea;
m_scrollArea->setContentsMargins(0,0,0,0);
m_scrollArea->setWidget(按钮容器);
m_scrollArea->SetWidgetResizeable(真);
m_scrollArea->setStyleSheet(“边框:1px纯蓝色”);
m_scrollArea->setSizePolicy(QSizePolicy::Expansing,QSizePolicy::Preferred);
firstRowLayout->addWidget(左,0,Qt::AlignLeft);
firstRowLayout->addWidget(m_scrollArea,1,Qt::AlignLeft);
firstRowLayout->addWidget(右、0、Qt::AlignLeft);
m_lineEdit=新的QLineEdit;
QPushButton*按钮=新的QPushButton;
QHBoxLayout*secondRowLayout=新的QHBoxLayout;
secondRowLayout->addWidget(m_lineEdit);
secondRowLayout->addWidget(按钮);
连接(按钮、信号(单击())、插槽(setButtonsCount());
mainLayout->addWidget(第一行,1,Qt::AlignLeft);
主布局->添加布局(第二行布局);
按钮->设置文本(“设置按钮计数”);
按钮容器->调整大小(m_按钮->按钮最佳宽度(),按钮容器->高度());
m_按钮->调整大小(m_按钮->按钮最佳宽度(),m_按钮->高度());
//面积->调整大小(100,面积->高度();
//area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
MainWidget::~MainWidget()
{
}
void MainWidget::setButtonsCount()
{
m_按钮->设置按钮计数(m_lineEdit->text().toInt());
}
下面是包含问题的整个Qt项目:
基本步骤包括:
CheckableButtonGroup
)必须设置QLayout::SetMinAndMaxSize
大小约束。然后它将足够大,可以容纳按钮。它的大小策略无关紧要,因为您只是将其放入qscrollara
区域,而不是另一个布局// https://github.com/KubaO/stackoverflown/tree/master/questions/scrollgrow-21253755
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif
class ButtonGroup : public QWidget {
Q_OBJECT
QHBoxLayout m_layout{this};
public:
ButtonGroup(QWidget * parent = 0) : QWidget{parent} {
m_layout.setSizeConstraint(QLayout::SetMinAndMaxSize); // <<< Essential
}
Q_SLOT void addButton() {
auto n = m_layout.count();
m_layout.addWidget(new QPushButton{QString{"Btn #%1"}.arg(n+1)});
}
};
class AdjustingScrollArea : public QScrollArea {
bool eventFilter(QObject * obj, QEvent * ev) {
if (obj == widget() && ev->type() == QEvent::Resize) {
// Essential vvv
setMaximumWidth(width() - viewport()->width() + widget()->width());
}
return QScrollArea::eventFilter(obj, ev);
}
public:
AdjustingScrollArea(QWidget * parent = 0) : QScrollArea{parent} {}
void setWidget(QWidget *w) {
QScrollArea::setWidget(w);
// It happens that QScrollArea already filters widget events,
// but that's an implementation detail that we shouldn't rely on.
w->installEventFilter(this);
}
};
class Window : public QWidget {
QGridLayout m_layout{this};
QLabel m_left{">>"};
AdjustingScrollArea m_area;
QLabel m_right{"<<"};
QPushButton m_add{"Add a widget"};
ButtonGroup m_group;
public:
Window() {
m_layout.addWidget(&m_left, 0, 0);
m_left.setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
m_left.setStyleSheet("border: 1px solid green");
m_layout.addWidget(&m_area, 0, 1);
m_area.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
m_area.setStyleSheet("QScrollArea { border: 1px solid blue }");
m_area.setWidget(&m_group);
m_layout.setColumnStretch(1, 1);
m_layout.addWidget(&m_right, 0, 2);
m_right.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_right.setStyleSheet("border: 1px solid green");
m_layout.addWidget(&m_add, 1, 0, 1, 3);
connect(&m_add, SIGNAL(clicked()), &m_group, SLOT(addButton()));
}
};
int main(int argc, char *argv[])
{
QApplication a{argc, argv};
Window w;
w.show();
return a.exec();
}
#include "main.moc"
//https://github.com/KubaO/stackoverflown/tree/master/questions/scrollgrow-21253755
#包括
#如果QT\u版本>=QT\u版本检查(5,0,0)
#包括
#恩迪夫
类按钮组:公共QWidget{
Q_对象
QHBoxLayout m_layout{this};
公众:
按钮组(QWidget*parent=0):QWidget{parent}{
m_layout.setSizeConstraint(QLayout::SetMinAndMaxSize);//宽度()+小部件()->宽度();
}
返回QScrollArea::eventFilter(obj,ev);
}
公众:
AdjustingScrolArea(QWidget*parent=0):qScrolArea{parent}{
void setWidget(QWidget*w){
qscrolrea::setWidget(w);
//碰巧QScrollArea已经过滤了小部件事件,
//但这是一个我们不应该依赖的实现细节。
w->installEventFilter(此);
}
};
类窗口:公共QWidget{
QGridLayout m_布局{this};
QLabel m_左{“>>”};
调整Crollarea m_区域;
QLabel m_right{“已经这样做了。现在我正试图找出一种方法来获得一行间距,我的意思是跳过一行,并在这个“虚拟”空间后放置新按钮…QLayout::addStretch()
或QLayout::addstruct()
应该可以做到这一点。