我可以在新项目的小部件上画一条线,但是在这里我不能在图像上画线,我想恢复光标相对于图像的位置,以计算以像素为单位的线距。
.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;
};
我还想在计算出直线的距离后画一个圆并计算表面是否有人有想法。
答案 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);
}