Qt中的动态布局
主要注意下面两点
一、QGroupBox组合框中添加控件
在QGroupBox组合框中加入控件,需要先把其它子控件使用布局结合在一起,
然后再调用QGroupBox::setLayout()函数,添加该布局。
即实现了把子控件添加到QGroupBox组合框中
//QGroupBox::setLayout()
二、动态布局
在布局类中调用removeWidget(); //删除布局中的子控件,
再在布局类中调用addWidget(); //添加子控件
即可实现动态布局
//mainLayout->removeWidget();
//mainLayout->addWidget();
下面给出代码示例
//.h文件
#include
#include
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
private:
//函数部分
//创建第一部分界面:旋转控件组合框
void createRotableGroupBox();
//创建第二部分界面:方向组合框
void createOptionsGroupBox();
//创建第三部分界面:按钮组合框
void createButtonBox();
//控件部分
//第一部分:QGroupBox控件
QGroupBox *rotableGroupBox;
QQueue rotableWidgets; //控件队列
//第二部分:QGroupBox控件
QGroupBox *optionsGroupBox;
QLabel *buttonsOrientationLabel;
QComboBox *buttonsOrientationComboBox;
//第三部分:QDialogButtonBox控件
QDialogButtonBox *buttonBox;
QPushButton *closeButton;
QPushButton *helpButton;
QPushButton *rotateWidgetsButton;
//布局
//总体布局
QGridLayout *mainLayout;
//第一部分中的控件布局
QGridLayout *rotableLayout;
//第二部分中的控件布局
QGridLayout *optionsLayout;
signals:
public slots:
//QComboBox中index改变产生currentIndexChanged()信号对应的槽函数
void buttonsOrientationChanged(int index);
//构建rotableGroupBox组合框中的四个子控件的动态布局
void rotateWidgets();
void help();
};
//.cpp文件
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent)
{
createRotableGroupBox();
createOptionsGroupBox();
createButtonBox();
mainLayout = new QGridLayout;
//主布局中添加3个组合框控件
mainLayout->addWidget(rotableGroupBox, 0, 0);
mainLayout->addWidget(optionsGroupBox, 1, 0);
mainLayout->addWidget(buttonBox, 2, 0);
setLayout(mainLayout);
//布局的大小限制(Constraint)模式:设置最小大小
mainLayout->setSizeConstraint(QLayout::SetMinimumSize);
setWindowTitle(tr("Dynamic layouts"));
}
void MyWidget::createRotableGroupBox()
{
rotableGroupBox = new QGroupBox(tr("Rotable Widgets"));
rotableWidgets.enqueue(new QSpinBox); //微调器入队
rotableWidgets.enqueue(new QSlider); //滑块
rotableWidgets.enqueue(new QDial); //刻度盘
rotableWidgets.enqueue(new QProgressBar); //进度条
//子控件个数
int n = rotableWidgets.count();
//四个控件首尾相连,关系形成一个环形,一个控件的数值改变随之后面的控件也改变
for(int i=0; iint)),
rotableWidgets[(i+1)%n], SLOT(setValue(int)));
}
rotableLayout = new QGridLayout;
//QGroupBox组合框控件,组合框控件中加入其它子控件,
rotableGroupBox->setLayout(rotableLayout);
//构建rotableGroupBox组合框中的四个子控件的动态布局
rotateWidgets();
}
void MyWidget::rotateWidgets()
{
//断言
Q_ASSERT(rotableWidgets.count()%2 == 0);
//按顺序遍历容器中的对象,遍历队列中的控件
foreach(QWidget *widget, rotableWidgets)
rotableLayout->removeWidget(widget); //删除布局中的子控件,动态布局
//控件队列中的头部控件出队后,入队尾
rotableWidgets.enqueue(rotableWidgets.dequeue());
const int n = rotableWidgets.count(); //4
for(int i=0; i2; ++i)
{
//添加控件到布局类中,动态布局,交换控件显示的位置
rotableLayout->addWidget(rotableWidgets[n-i-1], 0, i); //3,(0,0) 2,(0,1)
rotableLayout->addWidget(rotableWidgets[i], 1, i); //0,(1,0) 1,(1,1)
}
}
void MyWidget::createOptionsGroupBox()
{
optionsGroupBox = new QGroupBox(tr("Options"));
buttonsOrientationLabel = new QLabel(tr("Orientation of buttons:"));
buttonsOrientationComboBox = new QComboBox;
buttonsOrientationComboBox->addItem(tr("Horizontal"), Qt::Horizontal);
buttonsOrientationComboBox->addItem(tr("Vertical"), Qt::Vertical);
//QComboBox中的索引值(index)改变的信号连接到槽函数
connect(buttonsOrientationComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(buttonsOrientationChanged(int)));
optionsLayout = new QGridLayout;
optionsLayout->addWidget(buttonsOrientationLabel, 0, 0);
optionsLayout->addWidget(buttonsOrientationComboBox, 0, 1);
//设置第二列的延伸属性(strech factor)
optionsLayout->setColumnStretch(2,1);
optionsGroupBox->setLayout(optionsLayout);
}
void MyWidget::buttonsOrientationChanged(int index)
{
mainLayout->setSizeConstraint(QLayout::SetNoConstraint);
setMinimumSize(0,0);
//获取QComboBox中的方向信息
Qt::Orientation orientation = Qt::Orientation(
buttonsOrientationComboBox->itemData(index).toInt());
//判断方向是否改变
if(orientation == buttonBox->orientation())
return;
//控制buttonBox的布局
mainLayout->removeWidget(buttonBox);
int spacing = mainLayout->spacing();
QSize oldSizeHint = buttonBox->sizeHint() + QSize(spacing, spacing);
//设置按钮框的布局方向
buttonBox->setOrientation(orientation);
QSize newSizeHint = buttonBox->sizeHint() + QSize(spacing, spacing);
if(orientation == Qt::Horizontal)
{
mainLayout->addWidget(buttonBox, 2, 0);
resize(size() + QSize(-oldSizeHint.width(), newSizeHint.height()));
}
else
{
mainLayout->addWidget(buttonBox, 0, 3, 2, 1);
resize(size() + QSize(newSizeHint.width(), -oldSizeHint.height()));
}
mainLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
}
void MyWidget::createButtonBox()
{
buttonBox = new QDialogButtonBox;
closeButton = buttonBox->addButton(QDialogButtonBox::Close);
helpButton = buttonBox->addButton(QDialogButtonBox::Help);
rotateWidgetsButton = buttonBox->addButton(tr("Rotate &Widgets"),
QDialogButtonBox::ActionRole);
connect(rotateWidgetsButton, SIGNAL(clicked()), this, SLOT(rotateWidgets()));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
connect(helpButton, SIGNAL(clicked()), this, SLOT(help()));
}
void MyWidget::help()
{
QMessageBox::information(this, tr("Dynamic Layouts Help"),
tr("This example shows how the change layouts dynamically."));
}
代码来源于Qt官网,
链接:http://doc.qt.io/qt-5/qtwidgets-layouts-dynamiclayouts-example.html