1、需求分析
* 练习开发一个向导用户界面
- 在同一界面上展现不同的向导页面;
- 通过 “上一步” 和 “下一步” 按钮进行切换;
- 不同页面上的元素组件和组件排布都不相同;
- 页面中的组件通过布局管理器进行排布;
2、解决方案
* 通过嵌套预定义的布局管理器
* 通过布局嵌套进行界面设计
1 、整体,通过垂直布局管理器实现两行;
2 、第一部分占面积大,通过栈式布局管理器管理不同的页面;
3 、第二部分占面积较小,通过水平布局管理器实现两列;包含“上一步”、“下一步”
3、bug
warring:'preBtn' was not declared in this scope;
修改:
void initControl()
修改为 ---》
void Widget::initControl()
4、代码 Widget.cpp
#include "Widget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QFormLayout>
#include <QDebug>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
initControl();
}
void Widget::initControl()
{
QVBoxLayout* vLayout = new QVBoxLayout(); //垂直布局,将界面分为上、下两部分。
QHBoxLayout* hLayout = new QHBoxLayout(); //水平布局,将下部分再分为左、右两部分。
//QStackedLayout* sLayout = new QStackedLayout(); //栈式布局管理器,将上部分实现界面切换
preBtn.setText("Pre Page"); //设置按钮属性
preBtn.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); //(水平方向扩展,垂直方向固定)
preBtn.setMinimumSize(160,30); //最小尺寸
nextBtn.setText("Text Page");
nextBtn.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
nextBtn.setMinimumSize(160,30);
connect(&preBtn,SIGNAL(clicked()),this,SLOT(onPreBtnClicked())); //连接按钮与消息处理函数
connect(&nextBtn,SIGNAL(clicked()),this,SLOT(onNextBtnClicked()));
//为什么选clicked()?因为,需要与onPreBtnClicked()相似;
hLayout->addWidget(&preBtn); //将两个按钮放到水平布局管理器中,左
hLayout->addWidget(&nextBtn); //将两个按钮放到水平布局管理器中,右
sLayout.addWidget(get1stPage()); //*****点操作符;将栈式管理器管理的三个页面加入 sLayout 上部分;
sLayout.addWidget(get2ndPage());
sLayout.addWidget(get3rdPage());
vLayout->addLayout(&sLayout); //*****取地址;将两个对象放到垂直布局管理器中,对应部分;上部分
vLayout->addLayout(hLayout); //将两个对象放到垂直布局管理器中,对应部分;下部分
setLayout(vLayout); //将函数的水平布局管理器加入到主界面
}
QWidget* Widget::get1stPage() //三个函数分别创建三个不同的页面
{
QWidget* ret = new QWidget(); //返回Widget对象
QGridLayout* layout = new QGridLayout(); //定义对象
fLbl1.setText("This"); //他们拥有相同的父组件,他们相同的父组件为外层的Widget; 设置四个标签组件的名字
fLbl2.setText("is");
fLbl3.setText("1st");
fLbl4.setText("page");
layout->addWidget(&fLbl1, 0, 0); //指定每个组件在布局管理器的坐标
layout->addWidget(&fLbl2, 0, 1);
layout->addWidget(&fLbl3, 1, 0);
layout->addWidget(&fLbl4, 1, 1);
ret->setLayout(layout); //当布局管理器加入到返回的最终对象的时候;
qDebug() << ret;
qDebug() << fLbl1.parent();
qDebug() << fLbl2.parent();
qDebug() << fLbl3.parent();
qDebug() << fLbl4.parent();
return ret;
}
QWidget* Widget::get2ndPage()
{
QWidget* ret = new QWidget(); //返回Widget对象
QFormLayout* layout = new QFormLayout();
sLineEdit.setText("This is 2nd page");
layout->addRow("Hint:",&sLineEdit); //将第2个界面加入到页面
ret->setLayout(layout);
return ret;
}
QWidget* Widget::get3rdPage()
{
QWidget* ret = new QWidget(); //返回Widget对象
QVBoxLayout* layout = new QVBoxLayout(); //创建对象
tPushBtn1.setText("This is");
tPushBtn2.setText("3rd page");
layout->addWidget(&tPushBtn1);//将两个按钮加入第3个页面
layout->addWidget(&tPushBtn2);
ret->setLayout(layout);
return ret;
}
void Widget::onPreBtnClicked() //消息处理函数
{
int index = ((sLayout.currentIndex() - 1) + 3) % 3; //技巧:循环取到上一个页面的下标
sLayout.setCurrentIndex(index); //将获得的下标设置进去
}
void Widget::onNextBtnClicked()
{
int index = (sLayout.currentIndex() + 1) % 3;
sLayout.setCurrentIndex(index);
}
Widget::~Widget()
{
}