QT:内存泄漏和子类(自定义QWidget)问题

时间:2014-01-12 22:49:17

标签: c++ qt

我有一个主窗口应用程序,有3个主要模块,每个模块有6个子模块。每个子模型都包含不同类型的Gui小部件(如Qlineedit,Qlabel,QPushbutton,QGroupBox等...)。

我将子类化所有主要和子模块(继承QWidget)。每个主模块和子模块都是动态创建的。例如,当构建第一个主模块时,它还为6个子模块分配。但是,当应用程序关闭时,它不会释放所有6个子模块。可能存在泄漏问题,但我没想到。为什么。我想我的模块子类化有问题。

我的应用太大了,无法在此发布,因此我会发布2个基准代码。为了显示这个问题,这个主窗口应用程序有100个我的自定义QLineEdit对象(我知道它很奇怪,但它很好地解决了我的问题)。但是当应用程序关闭时,不会释放所有100个自定义Qlineedit对象。 (这里,我的自定义QLineedit类代表我的模块......)

我尝试了2种子类来理解这个问题。 1. BcInputBox继承QLineEdit 2. BcInputBox继承QWidget

我已经分别试过了两个,但问题是一样的。我花了一个多星期的时间,但我还没弄明白。

哪种方法会更好?我的设计错误是什么?

第一基准

// #####################################################
//                      Benchmark 1                   //
// #####################################################
//
//BcInputBox.h
#ifndef BCINPUTBOX_H
#define BBCINPUTBOX_H

#include <QLineEdit>

namespace BC {
const bool ReadOnly = true;
const bool Edit = false;
const bool Double = true;
const bool Name = false;
}

class BcInputBox: public QWidget
{
    Q_OBJECT
public:
    explicit BcInputBox(QWidget *parent = 0, bool editInfo = BC::Edit, bool inputInfo = BC::Double);
    ~BcInputBox();
    void setEditInfo(bool editInfo);
    void setInputInfo(bool inputInfo);
    QLineEdit *getInputBox() const;
    static int objCounter;
private:
    QLineEdit *inputBox;
};
#endif // BCINPUTBOX_H

//******************************************
//BcInputBox.cpp

#include <QDebug>
#include <QHBoxLayout>
#include <QValidator>
#include "BcInputBox.h"
#include "BcDoubleValidator.h"

int BcInputBox :: objCounter = 0;

BcInputBox::BcInputBox(QWidget *parent, bool editInfo, bool inputInfo):QWidget(parent)
{

    QHBoxLayout *hlay = new QHBoxLayout(this);
    inputBox = new QLineEdit(this);
    setEditInfo(editInfo);
    setInputInfo(inputInfo);
    hlay -> addWidget(inputBox);
    inputBox -> setStyleSheet("background-color: yellow;"
                              "border-radius: 8px;");
    qDebug() << objCounter++ << "BcInputBox()";

}
BcInputBox :: ~BcInputBox()
{
    //qDebug() << objCounter ;
    qDebug() << "~BcInputBox";
    delete inputBox;
}

void BcInputBox :: setEditInfo(bool editInfo)
{
    inputBox -> setReadOnly(editInfo);
}

void BcInputBox :: setInputInfo(bool inputInfo)
{

    if (!inputInfo){
        QRegExp rExp ("[A-Za-z0-9]{1,16}");
        inputBox -> setValidator(new QRegExpValidator(rExp, inputBox));
    }
    else {
        inputBox -> setValidator( new BcDoubleValidator( 0.0, 1000, 3,inputBox));
    }

}
QLineEdit *BcInputBox :: getInputBox() const
{
    return inputBox;
}
//******************************************
//MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include "subconsmod1.h"
#include "BcInputBox.h"

namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    BcInputBox *subSection[100];

};

#endif // MAINWINDOW_H
//******************************************
//MainWindow.cpp
#include <QtCore>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QVBoxLayout *hlay = new QVBoxLayout(ui->centralWidget);
    for (int i = 0; i < 100; ++i ){
        subSection[i] = new BcInputBox (ui->centralWidget);
        hlay -> addWidget(subSection[i]);}
    ui->centralWidget ->setLayout(hlay);
}

MainWindow::~MainWindow()
{

    delete ui;
}

第二个基准

// #####################################################
//                      Benchmark 2                   //
// #####################################################
//
//BcInput.h
#ifndef BCINPUT_H
#define BCINPUT_H

#include <QLineEdit>

class BcInput : public QLineEdit
{
    Q_OBJECT
public:
    explicit BcInput(QWidget *parent = 0);
    ~BcInput();
    static int counter;
signals:

public slots:

};

#endif // BCINPUT_H

//******************************************
//BcInput.cpp
#include <QDebug>
#include "bcinput.h"

int BcInput :: counter = 0;
BcInput::BcInput(QWidget *parent) :
    QLineEdit(parent)
{
    qDebug() << "BcInput()";
    qDebug() << counter++;
}

BcInput :: ~BcInput()
{
    qDebug() << "~BcInput()";
}
//******************************************
//MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "bcinput.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    BcInput *subSection[100];
};

#endif // MAINWINDOW_H

//******************************************
//MainWindow.cpp
#include <QtGui>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "bcinput.h"

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

    for(int i = 0; i<100;i++){
        subSection[i] = new BcInput(ui->centralWidget);
        hlay->addWidget(subSection[i]);}
        ui->centralWidget->setLayout(hlay);
}

MainWindow::~MainWindow()
{
    for(int i = 0; i<100;i++)
        delete subSection[i];
    delete ui;
}

0 个答案:

没有答案