找回密码
 立即注册
收起左侧

KS05-12 使用QStackedLayout实现向导界面

0
回复
4670
查看
[复制链接]
累计签到:41 天
连续签到:1 天
来源: 原创 2019-7-3 21:14:29 显示全部楼层 |阅读模式

马上注册,查看详细内容!注册请先查看:注册须知

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 baizy77 于 2019-7-16 20:42 编辑

版权声明
---------------------------------------------------------------------------------------------------------------------
该文章原创于Qter开源社区(www.qter.org
作者: 女儿叫老白
转载请注明出处!
---------------------------------------------------------------------------------------------------------------------
网页版课程源码 提取码:1uy7

引言
------------------------------------------------------------------------------------
   向导界面是一种比较特殊的界面,当我们单击"下一步"时,会切换到另外一个界面。有时候,我们希望整个向导在同一个父对话框界面中通过切换部分子界面达到显示不同步骤的效果,该怎么实现呢?

正文
------------------------------------------------------------------------------------
   本节课,我们将借助Qt的QStackedLayout类开发一个演示向导界面程序。顾名思义,QStackedLayout是一个layout部件。该类型部件用来对QWidget部件进行布局。而QStackedLayout的功能是实现堆栈式布局,也就是当某一个QWidget子部件显示时可以隐藏其它的QWidget子部件。
首先,我们拿到了src.baselinez中的初始代码,我们得到下面这些东西:
l  一个main() 函数;
l  一个CDialog类,该类是向导对话框的主界面;
l  3个用来实现向导步骤的子界面类:CStep1、CStep2、CStep3以及它们对应的ui文件;
我们现在要做的就是,
l  为3个向导子界面增加信号并添加按钮对应的槽函数,在槽函数中触发相关信号以便通知QStackedLayout对象切换页面;
l  在向导主界面中构建向导子界面对象、QStackedLayout对象并将向导子界面添加到QStackedLayout;
l  在向导主界面中将子界面的信号绑定到QStackedLayout的相关槽函数,以便在子界面中单击上一步、下一步时更新当前页面;
下面,我们分步骤实现。

1.  step1:为3个向导子界面增加信号并添加按钮对应的槽函数,在槽函数中触发相关信号
首先为CStep1子界面添加信号:
代码清单05-12-01
step1.h
  1. #pragma once

  2. #include <QWidget>

  3. #include "ui_step1.h"
  4. class CStep1 : public QWidget
  5. {
  6.     Q_OBJECT

  7. public:
  8.     /// 构造函数
  9.     CStep1(QWidget *parent = 0);

  10. Q_SIGNALS:
  11.     void showpage(int page_index);

  12. private slots:
  13.     void slot_next();

  14. private:
  15.     Ui::CStep1 ui;
  16. };
复制代码
因为QStackedLayout类的切换/设置当前索引页的接口为:
  1. void QStackedLayout::setCurrentIndex(int index)
复制代码
  所以,为了让子界面的上一步、下一步按钮能够触发QStackedLayout对象的切换当前页面槽函数,在代码清单05-12-01中,我们在第14~15行,为CStep1子界面类增加一个信号showpage(int pageindex),以便当单击下一步时触发该信号。该信号提供一个int类型的输入以便和QStackedLayout::setCurrentIndex(intindex)的参数保持一致。
    另外,在代码清单05-12-01中我们在第17~18行为CStep1子界面类增加一个槽函数,用来响应“下一步”按钮(ui.btnNext)被按下。
    现在来看一下CStep1类的实现:
代码清单05-12-02

step1.cpp
  1. #include <QPushButton>

  2. #include "step1.h"

  3. CStep1::CStep1(QWidget *parent)
  4.     : QWidget(parent)
  5. {
  6.     ui.setupUi(this);

  7.     connect(ui.btnNext, &QPushButton::clicked, this, &CStep1::slot_next);
  8. }

  9. void CStep1:: slot_next()
  10. {
  11.     emit showpage(1);
  12. }
复制代码
在代码清单05-12-02中,我们在第32~35行增加了槽函数slot_next(),以便响应“下一步”按钮(ui.btnNext)被按下。在该槽函数中,我们触发信号showpage()并且提供了参数值为1,表示切换到第1页(步)。该信号将在主界面类中被截获,后面在CDialog类中我们会介绍。
    另外,在第28行我们增加了将按钮与槽函数绑定的代码。这里我们使用了信号地址、槽函数地址的语法。
    同样的,我们为CStep2、CStep3子界面类做类似开发。
代码清单05-12-03

step2.h
  1. #pragma once

  2. #include <QWidget>

  3. #include "ui_step2.h"
  4. class CStep2 : public QWidget
  5. {
  6.     Q_OBJECT

  7. public:
  8.     /// 构造函数
  9.     CStep2(QWidget *parent = 0);

  10. Q_SIGNALS:
  11.     void showpage(int page_index);

  12. private slots:
  13.     void  slot_previous();
  14.     void slot_next();

  15. private:
  16.     Ui::CStep2 ui;
  17. };
复制代码
在代码清单05-12-03中,我们为类CStep2增加了同样的信号showpage(int page_index),并且为"上一步"、"下一步"按钮分别增加了槽函数slot_previous()、slot_next()。
    代码清单05-12-04

step2.cpp
  1. #include "step2.h"

  2. CStep2::CStep2(QWidget *parent)
  3.     : QWidget(parent)
  4. {
  5.     ui.setupUi(this);

  6. connect(ui.btnPrevious,
  7.         &QPushButton::clicked,
  8.         this,
  9.         &CStep2::slot_previous);
  10. connect(ui.btnNext,
  11.         &QPushButton::clicked,
  12.         this,
  13.         &CStep2::slot_next);  
  14. }

  15. void CStep2::slot_previous()
  16. {
  17.     emit showpage(0);
  18. }

  19. void CStep2::slot_next()
  20. {
  21.     emit showpage(2);

  22. }
复制代码
在代码清单05-12-04中,我们为类CStep2增加了槽函数的实现17~26行,并在槽函数中分别触发信号showpage,提供的参数值分别为0、2表示切换到第0页(步)、第2页(步)。
    代码清单05-12-05

step3.h
  1. #pragma once

  2. #include <QWidget>

  3. #include "ui_step3.h"

  4. QT_BEGIN_NAMESPACE

  5. QT_END_NAMESPACE

  6. class CStep3 : public QWidget
  7. {
  8.     Q_OBJECT

  9. public:
  10.     /// 构造函数
  11.     CStep3(QWidget *parent = 0);

  12. Q_SIGNALS:
  13.     void showpage(int page_index);
  14.     void closeWindow();

  15. private slots:
  16.     void slot_previous();
  17.     void slot_close();
  18. private:
  19.     Ui::CStep3 ui;
  20. };
复制代码
在代码清单05-12-05中,我们为类CStep3增加了类似的信号槽。不同之处在于我们还增加了一个信号closeWindow()和一个槽函数slot_close()用来发出关闭(退出)界面的信号。
        代码清单05-12-06

step3.cpp
  1. #include "step3.h"

  2. CStep3::CStep3(QWidget *parent)
  3.     : QWidget(parent)
  4. {
  5.     ui.setupUi(this);
  6. connect(ui.btnPrevious,
  7.         &QPushButton::clicked,
  8.         this,
  9.         &CStep3::slot_previous);
  10. connect(ui.btnClose,
  11.         &QPushButton::clicked,
  12.         this,
  13.         &CStep3::slot_close);  
  14. }
  15. void CStep3::slot_previous()
  16. {
  17.     emit showpage(1);
  18. }
  19. void CStep3::slot_close()
  20. {
  21.     emit closeWindow();
  22. }
复制代码
在代码清单05-12-06中,我们编写了信号槽的绑定与实现。其中第11行将关闭按钮(ui.btnClose)的单击信号绑定到槽函数CStep3::slot_close()。
    而在第20~23行的slot_close()槽函数中,触发了信号closeWindow(),以便主窗口截获该信号并退出主程序。
step2 在向导主界面中构建向导子界面对象、QStackedLayout对象并将向导子界面添加到QStackedLayout
    在第一步中,我们为子界面增加了相关信号、槽函数。在第二步中,我们将构建子界面对象和QStackedLayout对象。

代码清单05-12-07

dialog.cpp
  1. CDialog::CDialog(QWidget* parent) : QDialog(parent)
  2. {
  3.         ui.setupUi(this);

  4.     QStackedLayout* pStackLayout = new QStackedLayout(this);
  5.     CStep1* pWidgetStep1 = new CStep1(this);
  6.     CStep2* pWidgetStep2 = new CStep2(this);
  7.     CStep3* pWidgetStep3 = new CStep3(this);
  8.     pStackLayout->addWidget(pWidgetStep1);
  9.     pStackLayout->addWidget(pWidgetStep2);
  10.     pStackLayout->addWidget(pWidgetStep3);

  11.     pStackLayout->setCurrentIndex(0);
  12.     ui.horizontalLayout->addLayout(pStackLayout);

  13. }
复制代码
在代码清单05-12-07中,第5行,我们构建了QStackedLayout对象pStackLayout;
    在第6~9行分别构建了3个子界面(步骤)对象;
    在第9~11行将3个子界面(步骤)对象添加到pStackLayout布局对象;
    第13行,设置默认的页面(步骤)为第0步。可以看出,QStackedLayout布局堆栈中的子对象从0开始编号。
    第14行将pStackLayout对象添加到ui的整体布局。

    对象构建完毕,接下来进行信号槽绑定。
step3 在向导主界面中将子界面的信号绑定到QStackedLayout的相关槽函数,以便在子界面中单击上一步、下一步时更新当前页面
代码清单05-12-08

dialog.cpp
  1. CDialog::CDialog(QWidget* parent) : QDialog(parent)
  2. {
  3.         // ......

  4. connect(pWidgetStep1, &CStep1::showpage,
  5.         pStackLayout, &QStackedLayout::setCurrentIndex);
  6. connect(pWidgetStep2, &CStep2::showpage,
  7.        pStackLayout, &QStackedLayout::setCurrentIndex);
  8. connect(pWidgetStep3, &CStep3::showpage,
  9.          pStackLayout, &QStackedLayout::setCurrentIndex);

  10.     connect(pWidgetStep3, &CStep3::closeWindow, this, &CDialog::close);
  11. }
复制代码
在代码清单05-12-08中,我们在第5~10行,将3个子界面发出的showpage()信号绑定到pStackLayout对象的setCurrentIndex()槽函数,因为showpage(int page_index)信号也是提供一个int类型的参数,跟QStackedLayout::setCurrentIndex(int index)配套,所以我们可以将各个子界面的showpage()信号直接绑定到QStackedLayout::setCurrentIndex()槽函数。
    在代码清单05-12-08中,我们在第12行,将子界面3 pWidgetStep3对象发出的closeWindow信号绑定到CDialog::close()槽函数,以便当pWidgetStep3子界面的btnClose按钮被单击时可以正常退出整个界面(整个程序)。

结语
------------------------------------------------------------------------------------
   在本节中,我们为读者介绍了使用QStackedLayout开发向导式界面的方法,主要分为如下3个步骤:
l  为3个向导子界面增加信号并添加按钮对应的槽函数,在槽函数中触发相关信号以便通知QStackedLayout对象切换页面;如果希望直接触发QStackedLayout的setCurrentIndex()槽函数,那么我们设计的信号的参数列表必须与槽函数的参数列表保持一致。
l  在向导主界面中构建向导子界面对象、QStackedLayout对象并将向导子界面添加到QStackedLayout;
l  在向导主界面中将子界面的信号绑定到QStackedLayout的相关槽函数,以便在子界面中单击上一步、下一步时更新当前页面;在子界面中可以emit自定义的关闭信号以便在主界面中退出整个程序;
    大家掌握了吗?


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了