Unsolved drawing shapes onto QPixmap with QPaintEvent
-
I am trying to draw shapes onto a pixmap, but both need to be viewed in a QGraphicsView.
Currently the pixmap is loaded into the view, but when I press my mouse it won't add any points onto the pixmap. It does register the points perfectly, but I would like them to be visual.
Is there anyone who can help me with this?Thanks
#include "graphicsview.h" GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent) { scene = new QGraphicsScene(); this->setScene(scene); this->setAlignment(Qt::AlignLeft | Qt::AlignTop); LoadImage(); } void GraphicsView::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { QPointF point = mapToScene(event->pos()); double x = point.x(); double y = point.y(); qv_points << QPointF(x,y); } this->update(); } void GraphicsView::paintEvent(QPaintEvent* event) { QPainter painter(viewport()); painter.drawPixmap(event->rect(), pixmap); painter.setPen(QPen(Qt::green, 5)); painter.setBrush(QBrush(Qt::green, Qt::CrossPattern)); QPolygonF polygon; polygon << qv_points; painter.drawPolygon(polygon); painter.drawPoints(qv_points); } void GraphicsView::LoadImage() { QString filename = QFileDialog::getOpenFileName(this, tr("Open Image"), QDir::currentPath(), tr("Image Files (*.png *.jpg *.jpeg)")); pixmap = QPixmap(filename); QRectF sceneRect = this->sceneRect(); pixmap.scaled (sceneRect.width (),sceneRect.height (), Qt::KeepAspectRatio, Qt::SmoothTransformation); }
-
is there anyone who can help me?
-
Hi
Please allow 24 hours to get replies. The users here are in different time zones and
comes online at various times.Regarding your issues.
Did you inspect the point values and see they are actually inside the pixmap/seems valid.
If it paints the pixmap and u can see it, the points should also draw. -
@mrjj said in drawing shapes onto QPixmap with QPaintEvent:
Did you inspect the point values and see they are actually inside the pixmap/seems valid.
If it paints the pixmap and u can see it, the points should also draw.Yes, that's also what I thought. They seem to be valid (checked with debugger), but somehow the points won't show up. It's not possible that the pixmap is drawn upon the drawn points, is it?
-
@hobbyProgrammer
Hi
Well you draw the pixmap first so that is very unlikely.Is there a reason you draw directly on the View and not use
https://doc.qt.io/qt-5/qgraphicspixmapitem.html
for the pixmap ?I would try with some fixed values like from 0,0 100,100 200,200
and see. ( in paintevent)I suspect its just something with coordinate system
Since you call QPointF point = mapToScene(event->pos());
the points are in scene coordinates but i wonder if that will match
the views coordinates. -
@mrjj So I did it with fixed Points and that seems to work. But it doesn't seem to call the paintEvent when I add the points on a mousePress. It gets called once and after that it never gets called anymore. This is my current code:
#include "graphicsview.h" GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent) { scene = new QGraphicsScene(); this->setScene(scene); this->setAlignment(Qt::AlignLeft | Qt::AlignTop); LoadImage(); } void GraphicsView::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { qDebug() << "Pressed at" << mapToScene(event->pos()); QPointF point = mapToScene(event->pos()); double x = point.x(); double y = point.y(); qv_points << QPointF(x,y); } this->update(); } void GraphicsView::paintEvent(QPaintEvent* event) { QPolygonF polygon; qDebug() << qv_points; polygon << qv_points; QPainter painter(viewport()); painter.setPen(QPen(Qt::green, 5)); painter.setBrush(QBrush(Qt::green, Qt::CrossPattern)); QRect dirtyRect = event->rect(); image = pixmap.toImage(); painter.drawImage(dirtyRect, image, dirtyRect); painter.drawPolygon(polygon); this->update(); } void GraphicsView::LoadImage() { QString filename = QFileDialog::getOpenFileName(this, tr("Open Image"), QDir::currentPath(), tr("Image Files (*.png *.jpg *.jpeg)")); pixmap = QPixmap(filename); QRectF sceneRect = this->sceneRect(); pixmap.scaled (sceneRect.width (),sceneRect.height (), Qt::KeepAspectRatio, Qt::SmoothTransformation); QGraphicsPixmapItem pixmapItem(pixmap); }
I added the line
qDebug() << qv_points;
and it doesn't seem to get there since I get no debug information from that. I only get the debug info from the mouse press event.
-
Hi
But if you see the pixmap then it clearly goes there ? -
@mrjj yes, but it only seems to go there once. I see the pixmap and I see that it prints an empty QVector and it does that only once. When I press the mouse button it doesn't seem to update.
-
@hobbyProgrammer
Hi
You call this->update();
so it really should paint again.You could in paint event do
void GraphicsView::paintEvent(QPaintEvent* event)
{
static int cc=0;
qDebug() << "paintEvent cc=" << cc++;and see if count raises when you press mouse.
-
@mrjj I implemented the code that you said I should try, but it doesn't raise the cc.
-
Ok. that i cannot guess.
You can try with repaint() from mousePress.Also, in paintEvent
this->update();
Could cause infinite recursion so its not nice to call update from paintEvent -
@mrjj I removed the update and added the repaint, but it still didn't resolve the issue.
-
Ok. then i really cant guess.
Code seems fine and should work. -
@hobbyProgrammer
I would suggest calling the base implementation of mousepressevent as wellvoid GraphicsView::mousePressEvent(QMouseEvent *event) { QGraphicsView::mousePressEvent(event); if(event->button() == Qt::LeftButton) { QPointF point = mapToScene(event->pos()); double x = point.x(); double y = point.y(); qv_points << QPointF(x,y); } this->update(); }
-
-
@mrjj is is perhaps better to use drawForeground and drawBackground for this issue, or wouldn't it matter?
-
@hobbyProgrammer
Hi
well DrawForeground and DrawBackground is often used for Grid feature or
similar. However, if you pixmap is sort of a background type, it would make sense but i cant promise it works better since i do not see why it would not
call the paintEvent for the view. Or what it is you are seeing.Also since you do not seem to call QGraphicsView normal paint,
i wonder if you dont use any of QGraphicsView features besides
just drawing on it ? -
@mrjj Hi,
All the code I used, I posted here so if it's not in this part of the code, it's nowhere in the code.
I'm going to try to recreate the project step by step, maybe I'll find the mistake. -
@hobbyProgrammer
Hi
Just to be sure i understand the actual task.
You want to show an image and then draw points by clicking
on the image. These points should be "live" meaning they should not be combined with image but drawn on top of the image ?Is it a requirement that the image can be zoomed and panned around and those points follow the scaling?
-
@mrjj yes exactly! but when I zoom in and out I would like there to be a scrollbar so that I can view and edit the entire image and not just the upper part.