在图像的标签上画一条线并计算距离

时间:2019-06-07 10:08:50

标签: c++ qt

我可以在新项目的小部件上画一条线,但是在这里我不能在图像上画线,我想恢复光标相对于图像的位置,以计算以像素为单位的线距。

.cpp
------
MainWindow::MainWindow(QWidget *parent):
  QMainWindow(parent),
  ui(new Ui::MainWindow),
  start(0, 0), end(0, 0), firstClick(true)
{
    ui->setupUi(this);
  ui->label->setMouseTracking(true);
       ui->label->installEventFilter(this);
 }
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_actionOuvrir_triggered()
{
*************

************
   ui->label->setPixmap(QPixmap::fromImage(imgaxial));


}
bool MainWindow::eventFilter(QObject *object, QEvent *event)
 {
     if (object == ui->label && event->type() == QEvent::MouseMove) {
         QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

        mouseMoveEvent(mouseEvent);

     }
return false;
}
void MainWindow::mouseMoveEvent ( QMouseEvent * event )
{
    int x = event->x();
    int y = event->y();
    ui->label_9->setText(QString::number(x)+ ", "+QString::number(y));
}
void MainWindow::mousePressEvent(QMouseEvent *pQEvent)
{
  if (pQEvent->button() == Qt::LeftButton) {
    (firstClick ? start : end) = pQEvent->pos();
    firstClick = !firstClick;
    update();
    pQEvent->accept();
  }
}

void MainWindow::paintEvent(QPaintEvent *pQEvent)
{
  QMainWindow::paintEvent(pQEvent);
  if (!firstClick) return;
  QPainter painter(this);
  QPen pen(Qt::red);
  pen.setWidth(4);
  painter.setPen(pen);
  painter.drawLine(start, end);
}
.h
----



namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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


    ~MainWindow();



private slots:
    void on_actionFermer_triggered();

    void on_actionOuvrir_triggered();




private:


    Ui::MainWindow *ui;


    int mStartX;
       int mStartY;
       int mEndX;
       int mEndY;

       bool mFirstClick;
       bool mPaintFlag;
       QPoint start, end;
       bool firstClick;
protected:
         bool eventFilter(QObject *, QEvent*);
       void mouseMoveEvent(QMouseEvent*);
    void mousePressEvent(QMouseEvent * e) override;
   virtual  void paintEvent(QPaintEvent * e) override;


};

我还想在计算出直线的距离后画一个圆并计算表面是否有人有想法。

1 个答案:

答案 0 :(得分:0)

子类QLabel并将逻辑放入其中,而不使用事件过滤器。制作和维护起来会更容易:

class DrawLabel: public QLabel
{
    Q_OBJECT
public:
    DrawLabel(QWidget* parent=nullptr): QLabel(parent)
    {
        setMouseTracking(true);
    }

    void setPixmap(QPixmap const& pixmap)
    {
        QLabel::setPixmap(pixmap);
        setFixedSize(pixmap.size());
    }

    virtual void mousePressEvent(QMouseEvent* event) override
    {
        if (event->button() != Qt::LeftButton)
        {
            start = QPointF();
            end = QPointF();
        }
        if (start.isNull() || !end.isNull())
        {
            start = event->pos();
            end = QPointF();
        }
        else
        {
            end = event->pos();
            update();
        }
        qDebug() << Q_FUNC_INFO << start << end;
    }
    virtual void paintEvent(QPaintEvent* event) override
    {
        QLabel::paintEvent(event);
        if (start.isNull() || end.isNull())
            return;
        QPainter painter(this);
        painter.drawLine(start, end);
    }

    void mouseMoveEvent(QMouseEvent* event)
    {
        positionChanged(event->pos());
    }
signals:
    void positionChanged(QPoint const&);
private:
    QPointF start, end;
};

对于测试:

    QPixmap pix(QSize(40, 40));
    pix.fill(Qt::blue);


    QWidget* w = new QWidget;
    QVBoxLayout* layout = new QVBoxLayout(w);
    DrawLabel* label = new DrawLabel();
    label->setPixmap(pix);
    QLabel* position = new QLabel("");
    layout->addWidget(label);
    layout->addWidget(position);

    QObject::connect(label, &DrawLabel::positionChanged, [=](QPoint const& p) {position->setText(QString("Position: %0 ; %1").arg(p.x()).arg(p.y()));});
    w->show();

如果绝对要使用事件过滤器,请通过在其上画线来更新像素图图像。您只需要保留原始像素图:

bool MainWindow::eventFilter(QObject *object, QEvent *event)
 {
    if(object != label)
        return false;
     if (event->type() == QEvent::MouseMove) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        mouseMoveEvent(mouseEvent);
     } else if (event->type() == QEvent::MouseButtonPress)
     {
         QMouseEvent* mouseEvent = static_cast<QMouseEvent *>(event);
         if (mouseEvent->button() == Qt::LeftButton)
         {
            (firstClick ? start : end) = mouseEvent->pos();
             qDebug() << Q_FUNC_INFO << start << end << firstClick;
            if (!firstClick)
                drawLine();
            firstClick = !firstClick;
         }
     }
    return false;
}

void MainWindow::drawLine()
{
    QPixmap pix(origin);
    QPainter painter(&pix);
    painter.drawLine(start, end); // The event contains positions it the label coor sys. No need to map them

    label->setPixmap(pix);

}