2

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

}

正確に何が問題なのかを整理するのを手伝ってください。

4

2 に答える 2

3

QPainter painter(this);QLabelのpixmapの代わりにメインウィジェットに描画するようにQPainterを設定した行で。ブロックをこれに変更すると動作します:

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

編集:

レイアウトを見て、自動的に想定したように、QWidget からではなく QLabel から派生したことに気付きました。確かに、クラスlabel1内でレイアウトする必要はありません。imageviewerサブクラス化の全体的なポイントは、動作を実装し、イベントを必要に応じてフィルタリングし、必要に応じてそれらをメインウィジェットに追加することです

EDIT2:

Imageviewer クラスは QLabel から派生し、label1 とレイアウトを削除し、画像ではなく 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);
于 2013-06-22T07:36:27.383 に答える
-1

からクラスを派生させQLabelたので、別のクラスを作成QLabel *label1してラベルのレイアウト内に配置しないでください。それは意味がありません。なぜ誰かがラベルをラベルに入れるのでしょうか? 代わりに、オブジェクトを削除してラベルとしてlabel1使用する必要があります。imageviewerコンストラクターには、次のコードのみを含める必要があります。

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

問題が解決することを確認しました。

于 2013-06-22T08:31:57.480 に答える