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 ?
CodePudding user response:
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();
}