当前位置:   article > 正文

通俗易懂玩QT:QStackedWidget 学习

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

connect(pbtn_2, &QPushButton::clicked, [=]() {
    stack_widget->setCurrentIndex(1);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

三、示例

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

mainwindow.cpp

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

#include <QVBoxLayout>
#include <QStackedWidget>
#include <QPushButton>
#include <QDebug>

#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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

testwidget.cpp

#include "testwidget.h"
#include <QDebug>
#include <QLabel>
#include <QHBoxLayout>
#include <QTimer>

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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

testwidget.h

#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include <QWidget>

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

下面是运行后的界面图:
在这里插入图片描述
点击按钮后相对应的被注册的窗体会启动一个定时器,页面切换后定时器依然存在,页面也未被销毁,所以在单个页面开销比较大的时候,切换窗体后记得及时手动关闭窗体正在执行的内容。

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/961200
推荐阅读
相关标签
  

闽ICP备14008679号