Search code examples
c++qtqt5qgraphicsviewqgraphicsscene

Virtual paint() is not getting called while drawing Polyline


I am new to Qt, and wants to write code to change Qt's default selection behaviour. So I am trying to override virtual paint method. But paint method is not getting called.
Below code, just print the polyline and paint() tries to change its selection behaviour.

polyline.h

class Polyline : public QGraphicsPathItem
{
public:
    Polyline();
    virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        auto copied_option = *option;
        copied_option.state &= ~QStyle::State_Selected;
        auto selected = option->state & QStyle::State_Selected;
        QGraphicsPathItem::paint(painter, &copied_option, widget);
        if (selected)
        {
            painter->save();
            painter->setBrush(Qt::red);
            painter->setPen(QPen(option->palette.windowText(), 5, Qt::DotLine));
            painter->drawPath(shape());
            painter->restore();
        }
    }
    QGraphicsPathItem* drawPolyline();
};      
   

polyline.cpp

#include "polyline.h"

Polyline::Polyline()
{}

QGraphicsPathItem* Polyline::drawPolyline()
{
    QPolygonF polygon;
    polygon<< QPointF (150,450) << QPointF (350,450) <<QPointF (350,200) << QPointF (250,100)<<QPointF (150,200);

    QPainterPath pPath;

    pPath.addPolygon(polygon);
    QGraphicsPathItem* new_item = new QGraphicsPathItem(pPath);
    new_item->setPen(QPen(QColor("red"), 5));
    new_item->setPath(pPath);
    new_item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
    return new_item;
}

   

main.cpp

#include "polyline.h"
#include <QGraphicsScene>
#include <QGraphicsView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QGraphicsView view;
    QGraphicsScene scene;
    view.setScene(&scene);

    Polyline p;
    QGraphicsPathItem* poly = p.drawPolyline();
    scene.addItem(poly);
    view.show();
    return a.exec();
}

 

Where am I wrong ?


Solution

  • The problem is that you don't create any Polyline object and attach it to the window or a widget.

    As such there's just no Polyline object to call the paint function on.

    A simple solution it to have your drawPolyline function create a Polyline object instead of the QGraphicsPathItem object you create now:

    QGraphicsPathItem* new_item = new Polyline(pPath);
    

    Remember to modify the Polyline constructor to take the path, and forward it to the base QGraphicsPathItem class.


    Another improvement is to realize that drawPolyline doesn't really need to be a member function at all. And that it's rather badly named. I would suggest you define it as a source-file local function, renamed as createPolyline instead:

    namespace
    {
        QGraphicsPathItem* createPolyline()
        {
            // The body of your `drawPolyline` function
            // With the fix mentioned above
            // ...
        }
    }
    

    Then use this function instead:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QGraphicsView view;
        QGraphicsScene scene;
        view.setScene(&scene);
    
        scene.addItem(createPolyline());
        view.show();
        return a.exec();
    }