-
需求分析:(练习开发一个向导用户界面)
— 在同一个界面上展示不同的向导页面
— 通过 上一步 和 下一步 按钮进行切换
— 不同页面上的 元素组件 和 组件排布 都不相同
— 页面中的组件通过布局管理器进行排布 -
解决方案(通过布局嵌套进行界面设计)
其实这种东西本质只有一个页面,只是通过QStackedLayout
这个页面布局通过槽函数来切换页面。
-
通过
QStackLayout
管理不同的页面
-
通过子组件的方式生成不同的页面
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QStackedLayout>
class Widget : public QWidget
{
Q_OBJECT
private:
QStackedLayout slayout;
QPushButton PreBtn;
QPushButton NextBtn;
QLabel label1;
QLabel label2;
QLabel label3;
QLabel label4;
QLineEdit edit;
QPushButton btn1;
QPushButton btn2;
void initControl();
QWidget* get1stPage();
QWidget* get2ndPage();
QWidget* get3rdPage();
private slots:
void PreBtnClicked();
void NextBtnClicked();
public:
Widget(QWidget *parent = nullptr);
~Widget();
};
#endif // WIDGET_H
widget.cpp
#include "Widget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QFormLayout>
#include <QStackedLayout>
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent)
{
initControl();
}
void Widget::initControl()
{
QVBoxLayout* vlayout = new QVBoxLayout();
QHBoxLayout* hlayout = new QHBoxLayout();
PreBtn.setText("Pre Page");
PreBtn.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
PreBtn.setMinimumSize(120, 30);
NextBtn.setText("Next Page");
NextBtn.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
NextBtn.setMinimumSize(120, 30);
connect(&PreBtn, SIGNAL(clicked()), this, SLOT(PreBtnClicked()));
connect(&NextBtn, SIGNAL(clicked()), this, SLOT(NextBtnClicked()));
hlayout->addWidget(&PreBtn);
hlayout->addWidget(&NextBtn);
slayout.addWidget(get1stPage());
slayout.addWidget(get2ndPage());
slayout.addWidget(get3rdPage());
vlayout->addLayout(&slayout);
vlayout->addLayout(hlayout);
setLayout(vlayout);
}
QWidget* Widget::get1stPage()
{
QWidget* ret = new QWidget();
QGridLayout* layout = new QGridLayout();
label1.setText("This");
label2.setText("is");
label3.setText("1st");
label4.setText("page");
layout->addWidget(&label1, 0, 0);
layout->addWidget(&label2, 0, 1);
layout->addWidget(&label3, 1, 0);
layout->addWidget(&label4, 1, 1);
qDebug() << ret;
qDebug() << label1.parent();
qDebug() << label2.parent();
qDebug() << label3.parent();
qDebug() << label4.parent();
ret->setLayout(layout);
qDebug() << ret;
qDebug() << label1.parent();
qDebug() << label2.parent();
qDebug() << label3.parent();
qDebug() << label4.parent();
return ret;
}
QWidget* Widget::get2ndPage()
{
QWidget* ret = new QWidget();
QFormLayout* layout = new QFormLayout();
edit.setText("This is 2nd page");
layout->addRow("Hint:", &edit);
ret->setLayout(layout);
return ret;
}
QWidget* Widget::get3rdPage()
{
QWidget* ret = new QWidget();
QVBoxLayout* layout = new QVBoxLayout();
btn1.setText("This is");
btn2.setText("3rd page");
layout->addWidget(&btn1);
layout->addWidget(&btn2);
ret->setLayout(layout);
return ret;
}
void Widget::PreBtnClicked()
{
int index = (slayout.currentIndex()-1+3) % 3;
slayout.setCurrentIndex(index);
}
void Widget::NextBtnClicked()
{
int index = (slayout.currentIndex()+1) % 3;
slayout.setCurrentIndex(index);
}
Widget::~Widget()
{
}
- 注意事项
— 任意容器类的组件都可以指定布局管理器
— 同一个布局管理器的组件拥有相同的父组件
— 设置布局管理器的同时隐式指定了父子关系(setLayout
)
图中组件1 和 组件2 被同一个布局管理器管理,拥有相同的父组件。
- 小结:
— 布局管理器可以相互嵌套构成复杂用户界面
— 任意容器组件均可设置布局管理器
— 同一个布局管理器中的组件拥有相同的父组件
— 组件间的父子关系是 Qt 中内存管理的重要方式