Search code examples
qtqt5

Memory leak from Promoted class of QDoubleSpinBox


I am promoting the QDoubleSpinBox class as i want to catch the mouseDoubleClick Event.

This is the Promoted class.

class SumDoubleBox : public QDoubleSpinBox
{
    Q_OBJECT
public:

    explicit SumDoubleBox(QWidget* parent = nullptr);   
    void setSingleStep(double val);
    double singleStep() const;
    void stepBy(int steps) override;
protected:
    virtual void focusInEvent(QFocusEvent *e) override;         
public slots:       
    void setZero();
    void setOne();

signals:
    int signalUndoRedo();

private:
    double m_defaultStep = 1.0;
    double m_CurrentStep;
    bool m_stepUp;
};



SumDoubleBox::SumDoubleBox(QWidget* parent) : QDoubleSpinBox(parent)
{
    SumLineEdit* lineEdit = new SumLineEdit(this);
    setLineEdit(lineEdit);
    setMinimum(0.0);
    setMaximum(99999.0);
}

Since i am creating a pointer in the Constructor of the SumDoubleBox Class.

  SumLineEdit* lineEdit = new SumLineEdit(this);

Do i need to Explicitly delete this in the Destructor ?

///////////////////////////////////////////////////////////////// The Defination of the SumLineEdit class.

class SumLineEdit : public QLineEdit
{
    Q_OBJECT

public:
    explicit SumLineEdit(QWidget* parent = nullptr) {   };
protected:
    void mouseDoubleClickEvent(QMouseEvent* event) override;
};


void SumLineEdit::mouseDoubleClickEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
    {
        selectAll();
        event->accept();
        return;
    }
    QLineEdit::mouseDoubleClickEvent(event);
}

Solution

  • Since you've parented the new lineedit to the SumDoubleBox, it should get deleted with its parent.

    There is, however, a more Qt-centric way to handle this case that I would strongly recommend you use or at least look into: Installing an event filter on the built-in line edit and handling the events for it. I've made many spinbox variants, and this approach usually works out best:

    SumDoubleBox::SumDoubleBox( QWidget *parent ) :
        QDoubleSpinBox( parent )
    {
        lineEdit()->installEventFilter( this );
    }
    
    
    bool SumDoubleBox::eventFilter( QObject *object, QEvent *event )
    {
        if( object == lineEdit() && event->type() == QEvent::MouseButtonDblClick )
        {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
            if( mouseEvent->button() == Qt::LeftButton )
            {
                selectAll();
                event->accept();
                return true; //swallow the event
            }
    
        }
        return false; //let the event through to the lineedit
    }
    

    This makes the custom class entirely redundant. It's nice because inheritance is a big hammer that easily gets out of control as a codebase scales up, and if there are other simpler ways to achieve your goal, it's often worth considering.