在QLabel上的图像上绘制一个点

时间:2013-06-22 07:12:20

标签: image qt label

我在QLabel上显示了一张图片,想要在鼠标点击事件中获取坐标并在图像上绘制一个点。我能够得到坐标,但画家在我标签上的图像下面画点,我希望它在我的图像之上。

我的代码是:

的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);
            }

}

帮我解决究竟是什么问题?

2 个答案:

答案 0 :(得分:3)

使用行QPainter painter(this);设置QPainter以在主窗口小部件上绘制而不是QLabel的像素图。将块更改为此,它将起作用:

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));
    }

编辑:

刚刚注意到,你是从QLabel派生出来的,而不是QWidget,因为我自动假设,看着布局。实际上,我们的label1类内部不需要imageviewer和布局。子类化的整个要点是您以您希望的方式实现行为和过滤事件,然后在需要时将它们添加到主窗口小部件

EDIT2:

Imageviewer类应该从QLabel派生,删除label1和layout,并且不在图像上绘制,而是在imageviewer本身绘制,即this。然后你需要在你的程序中添加一个新类,例如,它来自QMainwindow或QWidget,你应该包括你的imageviewer类,创建布局并像这样添加你的类:

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

答案 1 :(得分:-1)

您从QLabel派生了您的课程,因此您不应创建另一个QLabel *label1并将其放在标签的布局中。这没有任何意义。为什么有人会在标签上贴上标签?您需要删除label1并使用imageviewer对象作为标签。您的构造函数应仅包含以下代码:

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

我已经检查过它可以解决您的问题。