Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Mapping from a promoted class



  • Hello fam! Quick question, I have a promoted label that displays my video. I need to draw a line on the video to help count my cars. However, when I draw it and pass it to my frames, the location is distorted. I have tried maptoglobal but to no avail. Below is the code. Secondly, is there a way to delete a qline painted by qpainter after drawing the line? Thanks.

    #ifndef COUNTERLINEPAINTER_H
    #define COUNTERLINEPAINTER_H
    
    #include <QObject>
    #include <QWidget>
    #include <QLabel>
    
    #include <QMouseEvent>
    #include <QEvent>
    #include <QDebug>
    #include <QPainter>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include "debugger.h"
    class CounterLinePainter : public QLabel
    {
        Q_OBJECT
    public:
        explicit CounterLinePainter(QWidget * parent = nullptr);
    public:
        void mousePressEvent(QMouseEvent* ev);
        void mouseReleaseEvent(QMouseEvent* ev);
        void mouseMoveEvent(QMouseEvent *ev);
        void paintEvent(QPaintEvent *ev);
    public:
        bool isMousePressed;
        bool drawStarted;
        bool isMouseMoving;
    
    public:
        int x, y;
        int lineStartX;
        int lineStartY;
        int lineStopX;
        int lineStopY;
    public:
        QPainter painter;
        QPixmap mPix;
        QLine mLine;
        QRect mRect;
        QPixmap mpPix;
        void drawLine();
        void drawRectangle();
        QPoint pointOne;
        QPoint pointTwo;
        QLine counterLine;
    
        QPoint lineStartPoint;
        QPoint lineStopPoint;
        bool drawMyLines;
    
        cv::Mat image;
    //    int* x, *y;
    //    int ii;
        QVector<QPoint>points;
        QImage qImage;
    signals:
        void sentLine(QLine countingLine);
    };
    
    #endif // COUNTERLINEPAINTER_H
    
    t#include "counterlinepainter.h"
    
    CounterLinePainter::CounterLinePainter(QWidget* parent): QLabel(parent)
    {
        isMousePressed = false;
        drawStarted = false;
        drawMyLines = true;
    }
    
    void CounterLinePainter::mousePressEvent(QMouseEvent *ev)
    {
        lineStartX = this->x = ev->x();
        lineStartY = this->y = ev->y();
        QPoint lineStartPoint(lineStartX, lineStartY);
        QWidget::mapToGlobal(lineStartPoint);
        counterLine.setP1(lineStartPoint);
        counterLine.setP2(lineStopPoint);
    }
    
    void CounterLinePainter::mouseReleaseEvent(QMouseEvent *ev)
    {
       emit sentLine(counterLine);
    }
    
    void CounterLinePainter::mouseMoveEvent(QMouseEvent *ev)
    {
        if(ev->type() == QEvent::MouseMove){
            lineStopX = this->x = ev->x();
            lineStopY = this->y = ev->y();
            QPoint endPoint(ev->pos());
            QWidget::mapToGlobal(endPoint);
            counterLine.setP2(endPoint);
            Debug(endPoint);
    
        }
        update();
    }
    
    void CounterLinePainter::paintEvent(QPaintEvent *ev)
    {
        QPainter painter(this);
        const QPixmap* pixmapPointer = pixmap();
        if(pixmapPointer){
             const QPixmap & pix = *pixmapPointer;
             qreal ratio = qMin(static_cast<qreal>(width()) / pix.width(), static_cast<qreal>(height()) / pix.height());
    
             QTransform transform;
             transform.scale(ratio, ratio);
    
             QRect sourceRect = transform.mapRect(ev->rect());
             painter.drawPixmap(ev->rect(), pix, sourceRect);
             QPen pen(Qt::darkGreen, 8, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
             painter.setPen(pen);
    
             if(drawMyLines){
                 painter.drawLine(counterLine);
                 LOGx("from painter P1");
                 Debug(counterLine.p1());
                 LOGx("=============================");
              LOGx("**************************************************************************");
                }
            }
    }
    
    void AnalysisWindow::receiveLineFromPainter(QLine newDrawnLine) {
        newLine = newDrawnLine;
        QPoint pointOne = newLine.p1();
        QPoint pointTwo = newLine.p2();
        LOGx("before map");
        Debug(pointOne);
        LOGx("=============================");
    
        ui->lblPlayer->mapFromParent(pointOne);
        ui->lblPlayer->mapFromParent(pointTwo);
        videoPlayer->counterP1 = cv::Point(pointOne.x(), pointOne.y());
        videoPlayer->counterP2 = cv::Point(pointTwo.x(), pointTwo.y());
        LOGx("after map");
        Debug(pointOne);
        LOGx("=============================");
        videoPlayer->showCounterLines = true;
    }
    

    sample.png

    [edit: Cleaned tags SGaist]


  • Lifetime Qt Champion

    @vinnadipo09 said in Mapping from a promoted class:

    is there a way to delete a qline painted by qpainter after drawing the line?

    No, you just don't draw it anymore when not needed.

    You should not use global coordinates when drawing on a widget.
    How/from where do you get the lines?



  • Thank you so much for your response
    But since I have promoted my qlabel to the painter class, it is using local coordinates of the label. I want to now show them on my video and to have the exact location, I need to have the global coordinates, right? Have you seen the Image I have attached?
    the lower green line is the one I am drawing with the qmouse event and the upper one is the one displayed on the video. Meaning that the latter is assuming global positon while the former is assuming local position.


  • Lifetime Qt Champion

    @vinnadipo09 said in Mapping from a promoted class:

    Have you seen the Image I have attached?

    No, I can't see any images in your posts.

    "But since I have promoted my qlabel to the painter class" - what do you mean by that? Also, do you use your label to show the frames from video? If you show the frames of the video in this label and draw lines you should use the local coordinates.
    And again: from where are the lines coming (their coordinates)?


  • Lifetime Qt Champion

    IMAGE:
    alt text



  • @jsulm I am getting my line from the promoted qlabel that also displays my video. I have promoted it to the class that I have attached in the code. The counterlinepainter class
    the image is here:
    https://ddgobkiprc33d.cloudfront.net/2c79c702-dfa4-416b-b482-510fcddedfa4.png
    For me to draw lines using mouse event and qlabel, I had to promote the label where I am drawing on to a painter class. Does that make sense?


  • Lifetime Qt Champion

    @vinnadipo09 said in Mapping from a promoted class:

    QWidget::mapToGlobal(lineStartPoint);

    This line does not have any effect as it does not change the parameter, but instead it returns new (mapped) coordinates.



  • @jsulm I finally got it to work but now when I resize my window, the line disappears or the location is immensely distorted. Can I make it to change with the size of the label? Another thing, how do I stop drawing the line once it is set up? And finally, the line on the video is drawn via cv::Line an a frame, still battling with how to use cv::Line to make it local on qlable. your response helped me get the coordinates. I hope you have an idea of how I can implement this.


  • Lifetime Qt Champion

    @vinnadipo09 said in Mapping from a promoted class:

    Another thing, how do I stop drawing the line once it is set up?

    You just don't draw it in paintEvent. I don't understand what the problem is?
    As long as you draw the line in paintEvent it will be visible.



  • @jsulm Thanks a bunch! Done and done! Now my only battle is scaling my line with the label. Remember, the line is cvLine and not Qline in the video. Thank you once again for your support.


Log in to reply