Search code examples
c++qtqt5qlineedit

Qt5 custom LineEdit widget (QLineEdit subclass) private variable crashes application


I've created a custom QLineEdit widget that handles drag and drop of files. Everything is working great with that part, but as soon as I add a Class variable the application crashes either at the construction of the class or at destruction:

  • When my variable is QString, it crashes at construction
  • When my variable is QString*, it crashed at destruction

I tried deleting the variable (QString*) in the destructor, same issue...

Any ideas?

Header:

#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

Source:

#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();
}

Solution

  • I was getting this as an error in debug: "invalid address specified to rtlfreeheap"

    I did some research on that and found out that it could be related to an internal issue with Qt (the way object constructors are called). I went back in my main application to see how I called my DropLineEdit object and notice that I forgot to remove the setAcceptDrops(true) after creating DropLineEdit Classe (the object was formerly a normal QLineEdit before I created DropLineEdit).

    Here was the function call:

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

    Changed to:

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

    After removing that redundant call (redundant since the acceptdrops was set in the constructor), I didn't get any application crash either with QString or QString* as member variable of DropLineEdit Class. I used a QString (not the pointer) and I was able to make my Class do what is was supposed to.

    Thanks for your replies guys. Much appreciated.