Offset in QMouseEvent based line drawing



  • Hi all,

    I am working on an application that draws lines based on mouse clicks. I made a sub class of QMainWindow called MainWindow. MainWindow has QGraphicsScene, QGraphicsView and QList<QPointF> as members.

    mainwindow.h

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    protected:
        void mousePressEvent(QMouseEvent * p_event) Q_DECL_OVERRIDE;
    
    private:
        QList<QPointF> PtList;
        QGraphicsScene * p_scene;
        QGraphicsView * p_view;
        QTextEdit * p_textEdit;
        QPixmap pix;
    
        void redrawScene();
        void redrawPersistentItems();
    };
    

    I am collecting the coordinates in the mousePressEvent, inserting them into QList and drawing lineItems on the Scene.


    mainwindow.cpp

    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        QWidget *widget = new QWidget;
        setCentralWidget(widget);
    
        // add pixmap item
        p_scene = new QGraphicsScene;
        p_scene->setSceneRect(0,0,400,400);
        pix = QPixmap("/Users/Vyata/qt/images/pic100x100.gif");
        p_scene->addPixmap(pix);
    
        p_view = new QGraphicsView(p_scene);
        p_view->setFrameShape(QGraphicsView::NoFrame);
        p_scene->setBackgroundBrush(Qt::yellow);
    
        p_textEdit = new QTextEdit();
        p_textEdit->setFrameShape(QFrame::NoFrame);
    
        // add view and textedit to layout
        QVBoxLayout *layout = new QVBoxLayout(widget);
        layout->addWidget(p_view);
        layout->addWidget(p_textEdit);
    
        widget->show();
    
        setWindowTitle("Draw with Mouse");
        resize(640,480);
    
    }
    
    MainWindow::~MainWindow()
    {
    
    }
    
    
    void MainWindow::mousePressEvent(QMouseEvent *p_event)
    {
        // collect mouse click coordinates using different methods provided by QMouseEvent
        QPointF ptL = p_event->localPos();
        QPointF ptS = p_event->screenPos();
        QPointF ptW = p_event->windowPos();
        QPoint ptG = p_event->globalPos();
        QPoint ptV = p_event->pos();
    
        // Print coordinates to QTextEdit
        QString strL = "LocalPos( " + QString::number(ptL.x()) +", "+ QString::number(ptL.y()) + " ); ";
        QString strS = "ScreenPos( " + QString::number(ptS.x()) +", "+ QString::number(ptS.y()) + " ); ";
        QString strW = "WindowPos( " + QString::number(ptW.x()) +", "+ QString::number(ptW.y()) + " ); ";
        QString strG = "GlobalPos( " + QString::number(ptG.x()) +", "+ QString::number(ptG.y()) + " ); ";
        QString strV = "ViewPos( " + QString::number(ptV.x()) + ", "+ QString::number(ptV.y()) + "); ";
    
        QString strScene = "Scene Width = " + QString::number(p_scene->sceneRect().width())
                +" Ht = " + QString::number(p_scene->sceneRect().height());
    
        p_textEdit->append(strL + strS + strW + strG + strV + "\n"+ strScene + "\n");
    
        // Add the Point to QList
        QPointF pt1 = p_view->mapToScene(ptV);
        PtList.append(pt1);
        MainWindow::redrawScene();
    }
    
    void MainWindow::redrawScene()
    {
        // clear scene and insert imiage and boundary rect
        p_scene->clear();
        redrawPersistentItems();
    
        // draw the ROI polygon from the QList
        int ListSize = PtList.size();
        QPointF ptVar1, ptVar2;
    
        if(ListSize == 2)
        {
            ptVar1 = PtList.last();
            ptVar2 = PtList.first();
            p_scene->addLine(ptVar1.x(),ptVar1.y(),ptVar2.x(),ptVar2.y());
        }
        else if (ListSize > 2)
        {
            for(int i = 0; i< ListSize-1; i++)
            {
                ptVar1 = PtList[i];
                ptVar2 = PtList[i+1];
                p_scene->addLine(ptVar1.x(),ptVar1.y(),ptVar2.x(),ptVar2.y());
            }
    
            ptVar1 = PtList.last();
            ptVar2 = PtList.first();
            p_scene->addLine(ptVar1.x(),ptVar1.y(),ptVar2.x(),ptVar2.y());
        }
    }
    
    // add pixmap and rect to scene
    void MainWindow::redrawPersistentItems()
    {
        p_scene->addPixmap(pix);
        QRectF rect = p_scene->sceneRect();
        p_scene->addRect(rect);
    
    }
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    I want my application to join all the lines I click on, creating a polygon. But I see an offset between where I click and where the actual coordinates are drawn on the screen.

    current output:

    screenshot

    In the screenshot I clicked along the corners of the 100 x 100 image, but my polygon is drawn with an offset.

    please help.