通俗易懂玩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 <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;
}

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

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);
    }
}

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

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

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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux 是一种开源操作系统,也是计算机世界中最重要的操作系统之一。它的主要目标是为用户提供稳定、可靠、高效的计算环境。与其他操作系统相比,Linux 的一个显著特点是它的开放性与自由性。任何人都可以免费获取、使用、修改和分发 Linux 操作系统。 要理解 Linux,首先需要了解 Linux 的基本概念和特点。Linux 是一个多用户、多任务的操作系统,这意味着多个用户可以同时登录使用系统,同时执行多个任务。它具有良好的稳定性和安全性,可以有效地保护用户的数据和系统。此外,Linux 还有一个庞大的软件库,可以满足各种各样的用户需求。 学习 Linux 的过程可以分为两个阶段。首先是了解 Linux 的基本命令和文件系统结构。Linux 使用命令行界面,所以学习常用的命令非常重要。一些常用的命令有:cd (进入目录)、ls (列出目录内容)、mkdir (创建目录)、rm (删除文件)、cp (复制文件)等。此外,还需要了解 Linux 的文件系统结构,例如根目录、用户目录、系统目录等。 第二个阶段是学习 Linux 的高级特性和应用。Linux 提供了丰富的网络功能,可以用于搭建 Web 服务器、数据库服务器等。另外,Linux 还支持多种编程语言和开发工具,如 C、C++、Python、Java 等。学习这些高级特性和应用可以帮助用户更好地利用 Linux 来完成各种任务。 为了更好地理解和学习 Linux,建议使用一些通俗易懂的教材。这些教材通常会从浅入深地介绍 Linux 的概念和特点,通过一些实例演示如何使用 Linux,并提供一些练习题来帮助读者巩固所学内容。此外,网络资源也是学习 Linux 的好帮手,可以参考一些在线教程和论坛,与其他 Linux 用户交流经验。 总之,学习 Linux 需要一定的时间和耐心,但掌握了 Linux,将为你带来更多的机会和可能。希望上述的回答对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我是混子我怕谁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值