0

我创建了一个自定义 QLineEdit 小部件来处理文件的拖放。该部分的一切都很好,但是一旦我添加了一个 Class 变量,应用程序就会在类的构造或销毁时崩溃:

  • 当我的变量是 QString 时,它在构造时崩溃
  • 当我的变量是 QString* 时,它在销毁时崩溃

我尝试在析构函数中删除变量(QString *),同样的问题......

有任何想法吗?

标题:

#ifndef DROPLINEEDIT_H
#define DROPLINEEDIT_H

#include <QLineEdit>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QFileInfo>
#include <QString>
#include <QDebug>


class DropLineEdit : public QLineEdit
{
    Q_OBJECT
public:
    explicit DropLineEdit(QWidget *parent = 0);
    ~DropLineEdit();

protected:
    virtual void dragEnterEvent(QDragEnterEvent *event);
    virtual void dropEvent(QDropEvent *event);
    virtual void dragLeaveEvent(QDragLeaveEvent *event);

signals:

public slots:

private:

    QString * mFileName;

};

#endif // DROPLINEEDIT_H

资源:

#include "droplineedit.h"

DropLineEdit::DropLineEdit(QWidget *parent) :
    QLineEdit(parent)
{
    setAcceptDrops(true);
    this->setReadOnly(true);
    this->setStyleSheet("QLineEdit { border: 2px solid gray ; border-radius: 8px ; padding: 0 6px }");
}

DropLineEdit::~DropLineEdit()
{
    if(!mFileName){
        delete mFileName;
    }
}

// **************************************** PROTECTED METHODS **************************************** //

void DropLineEdit::dragEnterEvent(QDragEnterEvent *event){
    this->setStyleSheet("QLineEdit { border: 3px solid black ; border-radius: 8px ; padding: 0 6px }");
    event->accept();
}
void DropLineEdit::dragLeaveEvent(QDragLeaveEvent *event){
    this->setStyleSheet("QLineEdit { border: 2px solid gray ; border-radius: 8px ; padding: 0 6px }");
    event->accept();
}

void DropLineEdit::dropEvent(QDropEvent *event){
    // Get the data. If multiple files are dropped, take only the first one and fetch save its info
    QList<QUrl> list = event->mimeData()->urls();
    QFileInfo * fileInfo = new QFileInfo(list.at(0).toLocalFile());

    qDebug() << fileInfo->absoluteFilePath();
    mFileName = new QString(fileInfo->absoluteFilePath());

    this->setText(fileInfo->fileName());
    this->setStyleSheet("QLineEdit { border: 2px solid gray ; border-radius: 8px ; padding: 0 6px }");
    event->accept();
}
4

2 回答 2

2

我在调试时收到此错误:“指定给 rtlfreeheap 的地址无效”

我对此进行了一些研究,发现它可能与 Qt 的内部问题(对象构造函数的调用方式)有关。我回到我的主应用程序,看看我是如何调用我的 DropLineEdit 对象的,并注意到我setAcceptDrops(true)在创建 DropLineEdit Classe 之后忘记删除(在我创建 DropLineEdit 之前,该对象以前是一个普通的 QLineEdit)。

这是函数调用:

DropLineEdit* Instrument::createDropLineEdit(){
    DropLineEdit * lineEdit = new DropLineEdit();
    lineEdit->setAcceptDrops(true);
    return lineEdit;
}

变成:

DropLineEdit* Instrument::createDropLineEdit(){
    DropLineEdit * lineEdit = new DropLineEdit();
    return lineEdit;
}

删除该冗余调用后(由于在构造函数中设置了acceptdrops,因此是冗余的),使用 QString 或 QString* 作为 DropLineEdit 类的成员变量,我没有遇到任何应用程序崩溃。我使用了一个 QString (不是指针),我能够让我的 Class 做应该做的事情。

谢谢你们的回复。非常感激。

于 2013-07-02T18:57:02.773 回答
2

将此添加到构造函数中:

mFileName = 0;

您需要初始化指针。否则它将具有随机值,您将无法检查您是否创建了对象。

修改析构函数:

delete mFileName;

如果对象不为 NULL,则需要删除它(您的版本相反)。delete将在内部执行检查。

请注意,如果mFileName = new QString...多次执行,将创建多个对象。如果需要避免内存泄漏,则需要在创建新对象之前删除先前的对象。

但是,以上所有信息都是为​​普通教育提供的。你不应该QString*在这里使用。非指针QString类成员会更正确。在这种情况下,您不需要使用newor delete,您根本不需要关心指针和内存。

于 2013-06-28T21:12:19.177 回答