Search code examples
c++qtqpixmap

Drawing a line between first and last QPoint on a QGraphicsView


I have a class that allows the user to draw a continuous line on an image by clicking anywhere on the image to create dots that automatically connect with each other.

GraphicsScene::GraphicsScene(QObject *parent) :
    QGraphicsScene(parent){

    //...
    qimOriginal = QImage((uchar*)src.data, src.cols, src.rows, src.step, QImage::Format_RGB888);
    addPixmap(QPixmap::fromImage(qimOriginal));
}

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent){
    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,1));
        }
    }
}

In my Dialog window that uses the GraphicsScene I have a button which on click returns the vector from GraphicsScene with the coordinates of the points. Before it returns the vector I want to draw a line between the first and last point of the QPolygon to create an area. Following is my GraphicsScene::getCoordinates() function:

std::vector<Point2f> GraphicsScene::getCoordinates(){
    qDebug() << pol.first() << pol.last();
    addLine(QLine(pol.first(),pol.last()),QPen(Qt::red,1));

    std::vector<Point2f> vecPoint;
    if (pol.size()>2){
        std::vector<QPoint> myVec = pol.toStdVector();

        for(int i=0; i<myVec.size(); i++) {
            QPoint point = myVec[i];
            Point2f p(point.x(), point.y());
            vecPoint.push_back(p);
        }

        pol.clear();
        this->clear();
        return vecPoint;
    }
    else{
         cout << "empty vector" << endl;
         return vecPoint;
    }

}

My problem is that for some reason addLine(QLine(pol.first(),pol.last()),QPen(Qt::red,1)); does not draw anything on my image.


Solution

  • As you said:

     I did have QThread::sleep(1); after the addLine()
    

    And believe me, it is source of your problem. QThread::sleep(1); sleeps, but it doesn't mean that your changes (your addLine) is showed on screen, no!

    And this code, you know it from one of my answers doesn't add line at the moment, it waits 1 second and after this you can see this line. It is thread issue.

    if(pol.size() > 1){
        QPainterPath myPath;
        myPath.addPolygon(pol);
        addPath(myPath,QPen(Qt::red,1));
    
        qDebug() << pol.first() << pol.last();
        addLine(QLine(pol.first(),pol.last()),QPen(Qt::red,1));
        Sleep(1000);//Sleep from WinApi
    }
    

    It source of your problem, but how to solve this? It is another question, but I can suggest you to try to use

    QTimer::singleShot(1000,this,SLOT(echo()));
    

    In slot you should clear your scene and of course you should remove

    QThread::sleep(1);
    

    from your code.