Unsolved drawing shapes onto QPixmap with QPaintEvent
-
@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.
-
Well im asking as you use the GraphicsView in a (in my opinion) odd way
as you treat it like the QWidget paint.
Normally one would use
https://doc.qt.io/qt-5/qgraphicspixmapitem.html
for the image and and make a custom QGraphicsItem to handle the overlay points
and in other ways used the features of the QGraphicsScene/view.Where are you seem to directly draw on the view as a normal Widget.
Its not criticism! i just wondered if you needed all of the QGraphicsScene/view stuff as doing with just a QWidget and paint is far more simple if
all the other features is not needed.And when you just overwrite paint for view (as the code you shown), then you are not using ANY of the selection/grouping/scaling etc of the Graphics Framework.
So i had to ask :) -
@mrjj okay, but I still don't get how to use the QGraphicsScene/View now.
Do I make the ScrollArea a QGraphicsView and then load the QGraphicsPixmap into the QGraphicsView?I don't really get the structure that is needed for this.
-
Hi
Normally the one would use QGraphicsPixmapItem
and maybe a custom item for the lines/polygon.
You would not need a ScrollArea -
@mrjj Okay so I tried to make a new graphicsview and this is the code.
It doesn't seem to load the pixmap.
It's probably a stupid mistake (I make them a lot), since I've wasted way too much time on this.#include "graphicsview.h" GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent) { scene = new QGraphicsScene(this); setScene(scene); } void GraphicsView::open() { filename = QFileDialog::getOpenFileName(this,tr("Open File"), QDir::currentPath(), tr("Image Files(*.png *.jpg *.jpeg)")); qDebug() << filename; QGraphicsPixmapItem *pixmap = scene->addPixmap(QPixmap(filename)); update(); }