我创建了一个自定义的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();
}
将其添加到构造函数:
mFileName = 0;
您需要初始化指针。否则,它将具有随机值,并且您将无法检查是否已创建对象。
修改析构函数:
delete mFileName;
若对象不是NULL,则需要删除它(您的版本正好相反)。delete
将在内部执行检查。
请注意,如果多次执行mFileName = new QString...
,将创建多个对象。如果需要避免内存泄漏,则需要在创建新对象之前删除以前的对象。
然而,上述所有信息都是为普通教育提供的。此处不应使用QString*
。非指针QString
类成员将更加正确。在这种情况下,您不需要使用new
或delete
,根本不需要关心指针和内存。
我在调试中得到了一个错误:"指定给rtlfreeheap的地址无效"
我对此进行了一些研究,发现这可能与Qt(对象构造函数的调用方式)的内部问题有关。我回到我的主应用程序,查看我是如何调用DropLineEdit对象的,并注意到我在创建DropLineEdit类后忘记删除setAcceptDrops(true)
(在创建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(而不是指针),我能够让我的类做应该做的事情。
谢谢你们的回复。非常感谢。