通俗易懂玩QT:QStackedWidget 学习

QStackedWidget 学习

一、介绍

业务需求,用到了 QStackWidget 这个类,然后程序存在很严重的内存泄露问题,所以特意研究了一下 QStackWidget 类,QStackWidget 类的功能是窗体切换,它比 QTabWidget 使用起来更为灵活,QStackWidget 类的窗体切换需要自己用 connect 来关联,同时也可以使用事件来触发。

二、使用

下面简单说一下 QStackWidget 类的一些用法(这里以两个 testwidget 类来做示范)

  1. 首先初始化窗体类与 QStackWidget 类
testwidget *tw_1 = new testwidget(1);
testwidget *tw_2 = new testwidget(2);

QStackedWidget *stack_widget = new QStackedWidget();
  1. 向 QStackWidget 类中添加窗体
stack_widget->addWidget(tw_1);
stack_widget->addWidget(tw_2);
  1. 切换到你想要最开始展现的窗体,默认为 0(即第一个被注册的窗体)
//选择以下任一方法使用即可,前者使用 index 来切换窗体,index 的值与你注册窗体时的先后顺序有关,注意不要越界使用,后者是通过窗体的名称切换窗体
stack_widget->setCurrentIndex(0);
stack_widget->setCurrentWidget(tw_1);
  1. 使用按钮的单击事件进行窗体切换
connect(pbtn_1, &QPushButton::clicked, [=]() {
    stack_widget->setCurrentIndex(0);
});

connect(pbtn_2, &QPushButton::clicked, [=]() {
    stack_widget->setCurrentIndex(1);
});

以上即为 QStackWidget 类的简单实用,不过值得注意的是,所有注册的窗体在切换过程中并不会得到释放,所以在窗体切换之后要及时关闭上一窗体的线程与定时器,否则内存可能突然大增,造成程序直接退出。

三、示例

这里以定时器为例,演示一下使用中的注意事项

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 
#include 
#include 

#include "testwidget.h"

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

    static int times = 0;

    testwidget *tw_1 = new testwidget(1);
    testwidget *tw_2 = new testwidget(2);
    testwidget *tw_3 = new testwidget(3);
    testwidget *tw_4 = new testwidget(4);

    QPushButton *pbtn_1 = new QPushButton("TEST ONE");
    QPushButton *pbtn_2 = new QPushButton("TEST TWO");
    QPushButton *pbtn_3 = new QPushButton("TEST THREE");
    QPushButton *pbtn_4 = new QPushButton("TEST FOUR");

    QStackedWidget *stack_widget = new QStackedWidget();
    stack_widget->addWidget(tw_1);
    stack_widget->addWidget(tw_2);
    stack_widget->addWidget(tw_3);
    stack_widget->addWidget(tw_4);
//    stack_widget->setCurrentIndex(0);

    QHBoxLayout *h_layout = new QHBoxLayout();
    h_layout->setMargin(0);
    h_layout->addWidget(pbtn_1);
    h_layout->addWidget(pbtn_2);
    h_layout->addWidget(pbtn_3);
    h_layout->addWidget(pbtn_4);

    QVBoxLayout *v_layout = new QVBoxLayout();
    v_layout->addLayout(h_layout);
    v_layout->addSpacing(0);
    v_layout->addWidget(stack_widget);

    ui->centralwidget->setLayout(v_layout);

    connect(pbtn_1, &QPushButton::clicked, [=]() {
        stack_widget->setCurrentIndex(0);
        qDebug() << stack_widget->currentWidget();
        tw_1->start(200);
    });

    connect(pbtn_2, &QPushButton::clicked, [=]() {
        stack_widget->setCurrentIndex(1);
        qDebug() << stack_widget->currentWidget();
        tw_2->start(200);
    });

    connect(pbtn_3, &QPushButton::clicked, [=]() {
        stack_widget->setCurrentIndex(2);
        qDebug() << stack_widget->currentWidget();
        tw_3->start(200);
    });

    connect(pbtn_4, &QPushButton::clicked, [=]() {
        stack_widget->setCurrentIndex(3);
        qDebug() << stack_widget->currentWidget();
        tw_4->start(200);
    });
}

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

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

testwidget.cpp

#include "testwidget.h"
#include 
#include 
#include 
#include 

testwidget::testwidget(int num):
    index(num),
    time(0),
    is_run(false){
    qDebug() << "This is the" << index << "widget.";

    QLabel *l_text = new QLabel(QString("widget %1").arg(index));
    QLabel *l_time = new QLabel();

    QHBoxLayout *h_lout = new QHBoxLayout;
    h_lout->addWidget(l_text);
    h_lout->addWidget(l_time);

    this->setLayout(h_lout);


    timer = new QTimer();

    connect(timer, &QTimer::timeout, [=] {
        l_time -> setText(QString("time: %1").arg(time ++));
    });
}

testwidget::~testwidget() {
    if(is_run) {
        is_run = false;
        timer -> stop();
    }
    qDebug() << "widget" << index << "over!";
}

void testwidget::start(int sec) {
    if(!is_run) {
        is_run = true;
        timer -> start(sec);
    }
}

testwidget.h

#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include 

class testwidget: public QWidget
{
    Q_OBJECT
public:
    testwidget(int num);
    ~testwidget();

    void start(int sec);

private:
    int index,
        time;

    bool is_run;

    QTimer *timer;
};

#endif // TESTWIDGET_H

下面是运行后的界面图:
通俗易懂玩QT:QStackedWidget 学习_第1张图片
点击按钮后相对应的被注册的窗体会启动一个定时器,页面切换后定时器依然存在,页面也未被销毁,所以在单个页面开销比较大的时候,切换窗体后记得及时手动关闭窗体正在执行的内容。

学习分享,一起成长!以上为小编的学习分享,若存在不当之处,请批评指正!

你可能感兴趣的:(QT学习,qt,qstackedwidget)