赞
踩
业务需求,用到了 QStackWidget 这个类,然后程序存在很严重的内存泄露问题,所以特意研究了一下 QStackWidget 类,QStackWidget 类的功能是窗体切换,它比 QTabWidget 使用起来更为灵活,QStackWidget 类的窗体切换需要自己用 connect 来关联,同时也可以使用事件来触发。
下面简单说一下 QStackWidget 类的一些用法(这里以两个 testwidget 类来做示范)
testwidget *tw_1 = new testwidget(1);
testwidget *tw_2 = new testwidget(2);
QStackedWidget *stack_widget = new QStackedWidget();
stack_widget->addWidget(tw_1);
stack_widget->addWidget(tw_2);
//选择以下任一方法使用即可,前者使用 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
下面是运行后的界面图:
点击按钮后相对应的被注册的窗体会启动一个定时器,页面切换后定时器依然存在,页面也未被销毁,所以在单个页面开销比较大的时候,切换窗体后记得及时手动关闭窗体正在执行的内容。
学习分享,一起成长!以上为小编的学习分享,若存在不当之处,请批评指正!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。