Qt开发自学6_多窗体切换

20200528

有3个窗体,怎么实现3个窗体之间的切换?(信号和槽)

思路:(1)分别有1,2,3号窗体

(2)1号窗体中,加上2号头文件,并且实例化2号的空间

(3)在1号窗体中,绑定2号窗体发送过来的信号,并用槽去处理(显示1号窗体)

(4)在1号窗体按钮上 show 2号窗体

 

创建第1个界面:PushButton*1、Label*2

 

创建第2个界面:PushButton*2、Label*2

把第二个页面的头文件引入第一个页面的头文件中:

 

【代码篇】

(有this)子窗体也在父窗体中显示

(不要this)并列窗体,分别显示。

 

(对象形式用全局变量指针形式用局部变量)

//第一种方式:会出现多个第2页面(局部变量压根就不行,局部指针多窗口)

//第二三种方式:只出现1个第2页面(全局变量,全局指针)

全局变量:只创建一个窗体,永远只有1个。

指针局部变量:创建多个窗体,因为点击1次,new1个对象,再点击1次,再new了1个对象。

          SecForm *tf1 = new SecForm();//指针形式

 

指针全局变量:很奈斯的方式啊,完美!

 

第一个页面GO>>第二个页面成功实现,代码如下:(firstform.cpp) 

#include "firstform.h"
#include "ui_firstform.h"
#include <QMovie>

FirstForm::FirstForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FirstForm)
{
    ui->setupUi(this);

    Init();//调用

    //绑定:处理1号窗体单击事件
    connect(ui->pushButton,SIGNAL(clicked(bool)),
            this,SLOT(doProcessClickGoSecForm(bool)));
}

FirstForm::~FirstForm()
{
    delete ui;
}
【Function】
 void FirstForm::Init(){
     //动画显示
     QMovie *movie = new QMovie("../0528Form2Form/Big.gif");//加载文件:注意目录的斜杠方向(是/)(不是\)//..表示当前文件的上级目录。完整目录E:/QtCode/0528Form2Form/Big.gif
     movie->start();//动起来
     ui->label->setMovie(movie);//固定位置
     ui->label->setScaledContents(true);//缩放内容

     //处理单击事件:跳转到第二页面
     connect(ui->pushButton,SIGNAL(clicked(bool)),
             this,SLOT(doProcessClickGoSecForm(bool)));

     pot2 = new SecForm();//空间分配。注意:千万不要用this指针,否则会在父窗体中显示
 }

 【Slots】
 void FirstForm::doProcessClickGoSecForm(bool){
     //创建第2个窗体,记得在头文件中引入第2个页面的头文件
     //(对象形式用全局变量;指针形式用局部变量或全局变量的比较)

     //【1】第一种方式:指针形式(局部),会出现多个第2页面(因为每次都new,会创建多个窗体)
     //     SecForm *tf1 = new SecForm(this);//指针形式(有this,子窗体将在父窗体中直接显示)
     //     tf1->show();

//     SecForm *tf1 = new SecForm();//指针形式:出现多个第2页面(无this,是并列窗体)
//     tf1->show();//指针形式:每次都new,会创建多个窗体 (new的意思就是“创建”)

     //【2】第二种方式:t1全局变量————只创建1个窗体(与局部变量做对比)

     //     SecForm t1;//仿照main.cpp,t1是局部变量
     //     t1.show();//这种方式行不通,因为资源是局部的,一开始就释放掉了。在该函数内部执行完,就没了。

     //     //头文件中定义全局变量 SecForm t1;//全局变量
     //          t1.show();//全局变量t1,只创建1个窗体

      //【3】第三种方式:把指针定义为全局的(只new一个对象)————一开始就分配好空间 pot2 = new SecForm();

     pot2->show(); // 头文件中定义全局指针 SecForm *pot2;
     this->hide();//隐藏当前页面,显示第2页面
 }

 

—————————————————分割线———————————————————

继续:第二页面的功能实现( Back 和 Next )

 

【返回上一页Back1】发射信号给第1个窗体,让它显示出来。

先绑定

    connect(ui->Back1,SIGNAL(clicked(bool)),this,SLOT(doProcessClickBack1()));

然后窗体2发信号,窗体1收信号

    emit SignalShowFirstForm(QString::number(clickCount));
 

 

实现代码如下:(secform.cpp) 窗体2发信号

#include "secform.h"
#include "ui_secform.h"
#include <QMovie>

SecForm::SecForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SecForm)
{
    ui->setupUi(this);

    Init();
}

SecForm::~SecForm()
{
    delete ui;
}
/【Function】/
void SecForm::Init(){

    clickCount = 0;//清空(按钮点击次数)

    //动画显示
    QMovie *movie = new QMovie("../0528Form2Form/jump.gif");//加载文件:注意目录的斜杠方向(是/)(不是\)//..表示当前文件的上级目录。完整目录E:/QtCode/0528Form2Form/Big.gif
    movie->start();//动起来
    ui->label->setMovie(movie);//固定位置
    ui->label->setScaledContents(true);//缩放内容

    //绑定
    connect(ui->Back1,SIGNAL(clicked(bool)),
            this,SLOT(doProcessClickBack1(bool)));

}

/【Slots】/
void SecForm::doProcessClickBack1(bool){

    clickCount++;   //每点击一次,就++

    //窗体2发射信号,通知第1个窗体显示。统计点击了多少次(发射了多少次信号)   //窗体1接收信号
    emit SignalShowFirstForm(QString::number(clickCount)); //number:把int转换为QString类型
    this->hide();//发射信号被处理后,第2窗体把自己隐藏
}

(firstform.cpp) 窗体1收信号

 

—————————————————分割线———————————————————

继续实现:【下一页】

 

创建新窗体ThdForm: LCD设置ui属性digitCount为2(显示两位)

 

QTimer对LCD的设置,代码如下:

(1)头文件中添加(thdform.h)

#include <QTimer>

private slots:
    void doProcessTimeOut();//超时信号处理
 
private:
    Ui::ThdForm *ui;
 
    int count;//全局计时
    QTimer *myTimer;
 
    void Init();//初始化对象

(2)源文件中(thdform.cpp)

#include "thdform.h"
#include "ui_thdform.h"

ThdForm::ThdForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ThdForm)
{
    ui->setupUi(this);

    Init();//调用初始化对象的函数
}

ThdForm::~ThdForm()
{
    delete ui;
}

/【Function】/
void ThdForm::Init(){

    count = 0;

    //LCD
    myTimer = new QTimer(this);//分配空间,对象释放this

    connect(myTimer,SIGNAL(timeout()),
            this,SLOT(doProcessTimeOut()));

    myTimer->start(100);//让时间跑起来:100ms一次
}


/【Slots】/
void ThdForm::doProcessTimeOut(){
    count++;

    if(count == 100)
        count =0;

    ui->lcdNumber->display(count);
}

 

(3)头文件中(secform.h)

第3个窗体的头文件添加到第2个窗体

用指针形式初始化第3个窗体对象的指针

        ThdForm *pot3;

 

槽函数:

private slots:
    void doProcessGoThdForm(bool);

 

(4)源文件中(secform.cpp)
分配空间,绑定 

 

 

—————————————————分割线———————————————————

继续实现:【返回第二页】

 

不能再new第2个窗体,因为第2个窗体的资源还在,只是隐藏起来了

如果在这里再创建第2个窗体,这就叫做内存泄漏

 

所以我们在第3个窗体中给第2个窗体发送通知:让其显示

void ThdForm::doProcessBack2(){
    //第3窗体给第2窗体发送信号,通知2号窗体显示————第2窗体接收信号
    emit SignalShowSecForm();
    this->hide();
}

第2个窗体接收信号,并处理

 connect(pot3,SIGNAL(SignalShowSecForm()),
            this,SLOT(doProcessShow()));

 

void SecForm::doProcessShow(){
    this->show();//【返回第二页面】显示
}

 

至此,大功告成!!!!!!

3个头文件代码如下:(*.h)

#ifndef FIRSTFORM_H
#define FIRSTFORM_H

#include <QWidget>
#include "secform.h"

namespace Ui {
class FirstForm;
}

class FirstForm : public QWidget
{
    Q_OBJECT

public:
    explicit FirstForm(QWidget *parent = 0);
    ~FirstForm();

private slots:
    void doProcessClickGoSecForm(bool);
    void doProcessSecFormRequest(QString);

private:
    Ui::FirstForm *ui;

    SecForm t1;
    SecForm *pot2;

    void Init();//声明方法
};

#endif // FIRSTFORM_H
#ifndef SECFORM_H
#define SECFORM_H

#include <QWidget>
#include "thdform.h"

namespace Ui {
class SecForm;
}

class SecForm : public QWidget
{
    Q_OBJECT

public:
    explicit SecForm(QWidget *parent = 0);
    ~SecForm();

private slots:
    void doProcessClickBack1(bool);
    void doProcessGoThdForm(bool);
    void doProcessShow();

signals:
    void SignalShowFirstForm(QString);


private:
    Ui::SecForm *ui;

    int clickCount;
    ThdForm *pot3;

    void Init();
};

#endif // SECFORM_H
#ifndef THDFORM_H
#define THDFORM_H

#include <QWidget>
#include <QTimer>

namespace Ui {
class ThdForm;
}

class ThdForm : public QWidget
{
    Q_OBJECT

public:
    explicit ThdForm(QWidget *parent = 0);
    ~ThdForm();

private slots:
    void doProcessTimeOut();//超时信号处理
    void doProcessBack2();

signals:
    void SignalShowSecForm();


private:
    Ui::ThdForm *ui;

    int count;//全局计时
    QTimer *myTimer;

    void Init();//初始化对象
};

#endif // THDFORM_H

 

 

3个源文件代码如下:(*.cpp)

#include "firstform.h"
#include "ui_firstform.h"
#include <QMovie>
#include <qDebug>

FirstForm::FirstForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FirstForm)
{
    ui->setupUi(this);

    Init();//调用

    //绑定:处理1号窗体单击事件
    connect(ui->pushButton,SIGNAL(clicked(bool)),
            this,SLOT(doProcessClickGoSecForm(bool)));
}

FirstForm::~FirstForm()
{
    delete ui;
}
【Function】
 void FirstForm::Init(){
     //动画显示
     QMovie *movie = new QMovie("../0528Form2Form/Big.gif");//加载文件:注意目录的斜杠方向(是/)(不是\)//..表示当前文件的上级目录。完整目录E:/QtCode/0528Form2Form/Big.gif
     movie->start();//动起来
     ui->label->setMovie(movie);//固定位置
     ui->label->setScaledContents(true);//缩放内容

     //处理单击事件:跳转到第二页面
     connect(ui->pushButton,SIGNAL(clicked(bool)),
             this,SLOT(doProcessClickGoSecForm(bool)));

     pot2 = new SecForm();//空间分配。注意:千万不要用this指针,否则会在父窗体中显示

     //窗体1接收来自窗体2的信号
     connect(pot2,SIGNAL(SignalShowFirstForm(QString)),
             this,SLOT(doProcessSecFormRequest(QString)));

 }

 【Slots】
 void FirstForm::doProcessClickGoSecForm(bool){
     //创建第2个窗体,记得在头文件中引入第2个页面的头文件
     //(对象形式用全局变量;指针形式用局部变量或全局变量的比较)

     //【1】第一种方式:指针形式(局部),会出现多个第2页面(因为每次都new,会创建多个窗体)
     //     SecForm *tf1 = new SecForm(this);//指针形式(有this,子窗体将在父窗体中直接显示)
     //     tf1->show();

//     SecForm *tf1 = new SecForm();//指针形式:出现多个第2页面(无this,是并列窗体)
//     tf1->show();//指针形式:每次都new,会创建多个窗体 (new的意思就是“创建”)

     //【2】第二种方式:t1全局变量————只创建1个窗体(与局部变量做对比)

     //     SecForm t1;//仿照main.cpp,t1是局部变量
     //     t1.show();//这种方式行不通,因为资源是局部的,一开始就释放掉了。在该函数内部执行完,就没了。

     //     //头文件中定义全局变量 SecForm t1;//全局变量
     //          t1.show();//全局变量t1,只创建1个窗体

      //【3】第三种方式:把指针定义为全局的(只new一个对象)————一开始就分配好空间 pot2 = new SecForm();

     pot2->show(); // 头文件中定义全局指针 SecForm *pot2;
     this->hide();//隐藏当前页面
 }


 void FirstForm::doProcessSecFormRequest(QString str){
     qDebug()<< str <<endl;//打印:单击了几次返回。
     this->show();//请求:显示当前页面
 }
#include "secform.h"
#include "ui_secform.h"
#include <QMovie>

SecForm::SecForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SecForm)
{
    ui->setupUi(this);

    Init();
}

SecForm::~SecForm()
{
    delete ui;
}
/【Function】/
void SecForm::Init(){

    clickCount = 0;//清空(按钮点击次数)

    //动画显示
    QMovie *movie = new QMovie("../0528Form2Form/jump.gif");//加载文件:注意目录的斜杠方向(是/)(不是\)//..表示当前文件的上级目录。完整目录E:/QtCode/0528Form2Form/Big.gif
    movie->start();//动起来
    ui->label->setMovie(movie);//固定位置
    ui->label->setScaledContents(true);//缩放内容

    //绑定
    connect(ui->Back1,SIGNAL(clicked(bool)),
            this,SLOT(doProcessClickBack1(bool)));

    pot3 = new ThdForm();//分配空间
    connect(ui->Next3,SIGNAL(clicked(bool)),
            this,SLOT(doProcessGoThdForm(bool)));

    connect(pot3,SIGNAL(SignalShowSecForm()),
            this,SLOT(doProcessShow()));
}

/【Slots】/
void SecForm::doProcessClickBack1(bool){

    clickCount++;   //每点击一次,就++

    //窗体2发射信号,通知第1个窗体显示。统计点击了多少次(发射了多少次信号)   //窗体1接收信号
    emit SignalShowFirstForm(QString::number(clickCount)); //number:把int转换为QString类型
    this->hide();//发射信号被处理后,第2窗体把自己隐藏
}

void SecForm::doProcessGoThdForm(bool){
    pot3->show();//【下一页】显示第3个窗体
    this->hide();//隐藏自己
}

void SecForm::doProcessShow(){
    this->show();//【返回第二页面】显示
}
#include "thdform.h"
#include "ui_thdform.h"

ThdForm::ThdForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ThdForm)
{
    ui->setupUi(this);

    Init();//调用初始化对象的函数
}

ThdForm::~ThdForm()
{
    delete ui;
}

/【Function】/
void ThdForm::Init(){

    count = 0;

    //LCD
    myTimer = new QTimer(this);//分配空间,对象释放this

    connect(myTimer,SIGNAL(timeout()),
            this,SLOT(doProcessTimeOut()));

    myTimer->start(100);//让时间跑起来:100ms一次

    connect(ui->Back2,SIGNAL(clicked(bool)),
            this,SLOT(doProcessBack2()));
}


/【Slots】/
void ThdForm::doProcessTimeOut(){
    count++;

    if(count == 100)
        count =0;

    ui->lcdNumber->display(count);
}

void ThdForm::doProcessBack2(){
    //第3窗体给第2窗体发送信号,通知2号窗体显示————第2窗体接收信号
    emit SignalShowSecForm();
    this->hide();
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卢奕冰2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值