Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to delete points from QPainterPath?



  • Hi, I am wondering is it possible to delete points from QPainterPath. I declare a QPainterPath variable and use it to draw lines by using moveTo and lineTo when the mouse is pressed or released. I wish to create a button that when it is pressed, it will delete the last line in the variable.


  • Lifetime Qt Champion

    There's no need to allocate QVector on the heap. You are only making it more complicated than necessary.


  • Lifetime Qt Champion

    Hi,

    From the looks of it you can't.

    If you only want one level of undo, then you could keep a copy of the path up to the last operation so you can copy it back to the "work path" if undone.



  • I've decided to use QVector<QPainterPath> to store my lines. But when I try to pop the last item out, it is not working. Also, when I use size() to print the size of my vector, it seems to increase despite nothing is drawn on the window.

    /*header file*/
    #ifndef WINDOW_H
    #define WINDOW_H
    
    #include <QWidget>
    #include <QFrame>
    #include <QPainterPath>
    #include <QMouseEvent>
    
    
    class window : public QWidget
    {
        Q_OBJECT
    
    public:
        window(QWidget *parent = nullptr);
        void mousePressEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
    
    public slots:
    
    private slots:
        void reversePath();
    
    private:
        QVector<QPainterPath> *path;
        QPainterPath *temp;
        void paintEvent(QPaintEvent *event);
    };
    #endif // WINDOW_H
    
    /*cpp file*/
    #include "window.h"
    #include <QDebug>
    #include <QtCore>
    #include <QBoxLayout>
    #include <QDebug>
    #include <QVectorIterator>
    #include <QVector>
    #include <QPainter>
    #include <QPushButton>
    
    
    window::window(QWidget *parent)
        : QWidget(parent)
    {
        setMinimumSize(QSize(500,500));
        path = new QVector<QPainterPath>;
        temp = new QPainterPath;
    
        QPushButton *reverse = new QPushButton("Reverse");
        connect(reverse, &QPushButton::clicked, this, &window::reversePath);
    
        QVBoxLayout *vbox = new QVBoxLayout(this);
        QHBoxLayout *hbox = new QHBoxLayout;
    
        hbox -> addWidget(reverse);
        hbox -> addStretch();
    
        vbox -> addLayout(hbox);
        vbox -> addStretch();
        setLayout(vbox);
    }
    
    
    void window::mousePressEvent(QMouseEvent *e)
    {
        temp -> moveTo(QPoint(e->x(),e->y()));
    }
    
    void window::mouseReleaseEvent(QMouseEvent *e)
    {
        temp -> lineTo(QPoint(e->x(),e->y()));
        update();
    }
    
    void window::reversePath(void)
    {
        path -> pop_back();
        qDebug()<<path -> size();
    }
    
    void window::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        path->append(*temp);
        QVectorIterator<QPainterPath> iter(*path);
        while(iter.hasNext()){
            painter.drawPath(iter.next());
        }
    }
    
    

    Printed result when I press the reverse button
    28 41 53 65 95


  • Lifetime Qt Champion

    There's no need to allocate QVector on the heap. You are only making it more complicated than necessary.



  • @SGaist I assumes that what you mean is for me to delete the line path = new QVector<QPainterPath>, but when I remove this line and run the program. It shows "The program has unexpectedly finished." What might be wrong?


  • Lifetime Qt Champion

    Because you are now using an invalid pointer.

    Use the stack for QVector.



  • Even though I've changed the vector declaration from QVector<QPainterPath> *path to QVector<QPainterPath> path, but the output when I press the button is still increasing each time.
    16 28 35...


  • Lifetime Qt Champion

    Well, you are adding new points to temp on every click and only adding its content to your vector on paintEvent which is a bad idea because paintEvent might get called a lot of time. Therefore temp acts just the same as before you added your vector of QPainterPath.



  • Thank you! I've solved my problem now. It is just my interest to know why paintEvent will be called a lot of time, as from what I learn, it will only be called when the signal update() is detected.


  • Lifetime Qt Champion

    There are a lot of reasons for paintings to happen. Moving the window, having something else coming through said window, etc.


Log in to reply