2014-09-21 448 views
1

我的GUI中有一个标签,将图像显示为QPixmap。我希望能够通过单击图像上的任意位置来选择起点,然后通过单击图像的其他部分在其他位置创建第二个点,从而在图像上绘制出连续的线条。放置第二个点后,这两个点应该立即连接,并且我希望能够通过在图像上放置更多点来继续同一行。如何使用点在QPixmap上绘制一条线

虽然我知道如何绘制QPixmap上的东西,但我需要用来获取点坐标的鼠标事件令我感到困惑,因为我对Qt还是比较新的。

任何解决方案的例子将不胜感激。

+0

请参阅我的编辑,我添加了非常重要的改进,如我所承诺的。 – Chernobyl 2014-09-21 15:16:56

回答

3

为了这个目的,我建议你使用QGraphicsView。使用我的代码片段,完美的作品。

子类QGraphicsScene

#ifndef GRAPHICSSCENE_H 
#define GRAPHICSSCENE_H 

#include <QGraphicsScene> 
#include <QPoint> 
#include <QMouseEvent> 
class GraphicsScene : public QGraphicsScene 
{ 
    Q_OBJECT 
public: 
    explicit GraphicsScene(QObject *parent = 0); 

signals: 

protected: 
    void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); 

public slots: 
    private: 

    QPolygon pol; 

}; 

#endif // GRAPHICSSCENE_H 

.cpp文件:

#include "graphicsscene.h" 
#include <QDebug> 
#include <QGraphicsSceneMouseEvent> 
#include <QPainter> 

GraphicsScene::GraphicsScene(QObject *parent) : 
    QGraphicsScene(parent) 
{ 
addPixmap(QPixmap("G:/2/qt.jpg"));//your pixmap here 
} 

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) 
{ 
    //qDebug() << "in"; 
    if (mouseEvent->button() == Qt::LeftButton) 
    { 

     QPoint pos = mouseEvent->scenePos().toPoint(); 
     pol.append(pos); 
     if(pol.size() > 1) 
     { 
       QPainterPath myPath; 
       myPath.addPolygon(pol); 
       addPath(myPath,QPen(Qt::red,2)); 
     } 
    } 
} 

用法:

#include "graphicsscene.h" 
//... 
GraphicsScene *scene = new GraphicsScene(this); 
ui->graphicsView->setScene(scene); 
ui->graphicsView->show(); 

结果:

enter image description here

如果你想保存新的像素图(或只是让像素映射)的图像,使用此代码:

QPixmap pixmap(ui->graphicsView->scene()->sceneRect().size().toSize()); 
QString filename("example.jpg"); 
     QPainter painter(&pixmap); 
     painter.setRenderHint(QPainter::Antialiasing); 
     ui->graphicsView->scene()->render(&painter, pixmap.rect(),pixmap.rect(), Qt::KeepAspectRatio); 
     painter.end(); 

     pixmap.save(filename); 

随着render()你也可以抓住你的场景的不同区域。

但是这段代码可以更好:我们创建并绘制相同的多边形。如果我们可以记住最后一个绘制的点,那么我们可以逐行绘制(行的开始是最后一行的结束)。在这种情况下,我们不需要所有的点,我们只需要最后一点。

正如我答应(代码改进):只提供额外的变量QPoint last;而不是QPolygon pol;并使用下面的代码:

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) 
{ 
    //qDebug() << "in"; 
    if (mouseEvent->button() == Qt::LeftButton) 
    { 

     QPoint pos = mouseEvent->scenePos().toPoint(); 
     if(last.isNull()) 
     { 
      last = pos; 
     } 
     else 
     { 
      addLine(QLine(last,pos),QPen(Qt::red,2)); 
      last = pos; 
     } 
    } 
} 

正如你所看到的,你只存储最后一点,油漆只有最后一行。用户可以点击几千次,现在你不需要存储这些不必要的点,并做这不必要的重新绘制。

+0

为了回答这个问题,你可以添加代码来获取结果作为'QPixmap'。 – hyde 2014-09-21 12:54:57

+0

@hyde已经完成。 – Chernobyl 2014-09-21 13:05:32