Я создал собственный виджет QLineEdit, который обрабатывает перетаскивание файлов. С этой частью все работает отлично, но как только я добавляю переменную Class, приложение вылетает либо при создании класса, либо при разрушении:
Я попытался удалить переменную (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*
Вот. Non-указатель QString
Ученик будет намного правильнее. В этом случае вам не нужно использовать new
или же delete
Вам не нужно заботиться об указателях и памяти вообще.
Я получаю это как ошибку в отладке: «неверный адрес указан для rtlfreeheap»
Я провел некоторое исследование по этому вопросу и выяснил, что это может быть связано с внутренней проблемой в Qt (как называются конструкторы объектов). Я вернулся в свое основное приложение, чтобы посмотреть, как я вызывал свой объект DropLineEdit, и заметил, что забыл удалить setAcceptDrops(true)
после создания DropLineEdit Classe (ранее объект был обычным QLineEdit до того, как я создал DropLineEdit).
Здесь был вызов функции:
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 (не указатель), и я смог заставить свой класс делать то, что должен был.
Спасибо за ваши ответы, ребята. Очень признателен.