Nishu
Nishu

Reputation: 191

drawing a point over an image on QLabel

I displayed a picture on QLabel and wanted to take coordinates and paint a point on image on mouse click event. I am able to get coordinates but painter is painting point below my image on label, i want it above my image.

My code is :

main.cpp

#include "imageviewer.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    imageviewer w;
    w.showMaximized();

    return a.exec();
}

imageviewer.h

#include <QPushButton>

class imageviewer : public QLabel
{
    Q_OBJECT

public:
    explicit imageviewer(QWidget *parent = 0);

private slots:

    void mousePressEvent(QMouseEvent * e);
    void paintEvent(QPaintEvent * e);

private:

    QLabel *label1 ;
    int mFirstX;
    int mFirstY;
    bool mFirstClick;
    bool mpaintflag;

};

#endif

imageviewer.cpp

#include <QtGui>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "imageviewer.h"
#include <QDebug>

imageviewer::imageviewer(QWidget *parent)
    : QLabel(parent)
{


    label1 = new QLabel;
    label1->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    QPixmap pm1("/home/nishu/Pictures/img_0002.jpg");
    label1->setPixmap(pm1);
    label1->adjustSize();
    label1->setScaledContents(true);

    QHBoxLayout *hlayout1 = new QHBoxLayout;
    hlayout1->addWidget(label1);

    setLayout(hlayout1);
}

void imageviewer :: mousePressEvent(QMouseEvent *e)
{
    mFirstX=0;
    mFirstY=0;
    mFirstClick=true;
    mpaintflag=false;

    if(e->button() == Qt::LeftButton)
            {
                //store 1st point
                if(mFirstClick)
                {
                    mFirstX = e->x();
                    mFirstY = e->y();
                    mFirstClick = false;
                    mpaintflag = true;
                    qDebug() << "First image's coordinates" << mFirstX << "," << mFirstY ;
                    update();

                }

            }
}

void imageviewer :: paintEvent(QPaintEvent * e)
{

    QLabel::paintEvent(e);

    if(mpaintflag)
    {
               QPainter painter(this);
               QPen paintpen(Qt::red);
               paintpen.setWidth(10);
               QPoint p1;
               p1.setX(mFirstX);
               p1.setY(mFirstY);
               painter.setPen(paintpen);
               painter.drawPoint(p1);
            }

}

Help me to sort out what exactly problem is?

Upvotes: 2

Views: 11495

Answers (2)

Shf
Shf

Reputation: 3493

with line QPainter painter(this); you set QPainter to draw on your main widget instead of QLabel's pixmap. Change block to this and it will work:

if(mpaintflag)
    {
           QImage tmp(label1->pixmap()->toImage());
           QPainter painter(&tmp);
           QPen paintpen(Qt::red);
           paintpen.setWidth(10);
           QPoint p1;
           p1.setX(mFirstX);
           p1.setY(mFirstY);
           painter.setPen(paintpen);
           painter.drawPoint(p1);
           label1->setPixmap(QPixmap::fromImage(tmp));
    }

EDIT:

Just noticed, that you derived from QLabel, not from QWidget, as i assumed automatically, looking at layout. Indeed, you don't need label1 and layout inside of our imageviewer class. That whole point of subclassing is that you implement behavior and filter events the way you want it and then you add them to main widget if that is needed

EDIT2:

Imageviewer class should be derived from QLabel, remove label1 and layout, and paint not on image, but on imageviewer itself, i.e. this. Then you need to add new class to your program, which is derived from QMainwindow or QWidget for example, where you should include your imageviewer class, create layout and add your class to it like this:

#include "imageviewer.h"
//.... somewhere in constructor ....
imageviewer *viewer1=new imageviewer(this); // creating new object of imageviewer
viewer1->setPixmap(...);
hlayout1->addWidget(viewer1);

Upvotes: 3

Pavel Strakhov
Pavel Strakhov

Reputation: 40492

You derived your class from QLabel, so you should not create another QLabel *label1 and put it inside label's layout. That doesn't make any sense. Why would anyone put a label into a label? You need to remove label1 and use the imageviewer object as a label instead. Your constructor should contain only the following code:

setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
QPixmap pm1(...);
setPixmap(pm1);
adjustSize();
setScaledContents(true);

I've checked that it fixes your problem.

Upvotes: -1

Related Questions