QStackedWidget 学习
一、介绍
业务需求,用到了 QStackWidget 这个类,然后程序存在很严重的内存泄露问题,所以特意研究了一下 QStackWidget 类,QStackWidget 类的功能是窗体切换,它比 QTabWidget 使用起来更为灵活,QStackWidget 类的窗体切换需要自己用 connect 来关联,同时也可以使用事件来触发。
二、使用
下面简单说一下 QStackWidget 类的一些用法(这里以两个 testwidget 类来做示范)
- 首先初始化窗体类与 QStackWidget 类
testwidget *tw_1 = new testwidget(1);
testwidget *tw_2 = new testwidget(2);
QStackedWidget *stack_widget = new QStackedWidget();
- 向 QStackWidget 类中添加窗体
stack_widget->addWidget(tw_1);
stack_widget->addWidget(tw_2);
- 切换到你想要最开始展现的窗体,默认为 0(即第一个被注册的窗体)
//选择以下任一方法使用即可,前者使用 index 来切换窗体,index 的值与你注册窗体时的先后顺序有关,注意不要越界使用,后者是通过窗体的名称切换窗体
stack_widget->setCurrentIndex(0);
stack_widget->setCurrentWidget(tw_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
下面是运行后的界面图:
点击按钮后相对应的被注册的窗体会启动一个定时器,页面切换后定时器依然存在,页面也未被销毁,所以在单个页面开销比较大的时候,切换窗体后记得及时手动关闭窗体正在执行的内容。
学习分享,一起成长!以上为小编的学习分享,若存在不当之处,请批评指正!