[SOLVED] QMouseEvent, QPainter and OpenCv



  • Hi guys,

    I'm using QT and OpenCV to show some images, as described in this video:

    http://www.youtube.com/watch?v=YaAeohyZOWU

    Now, I need to use QMouseEvent and QPainter to get the mouse coordinates and draw an "x" (or whatever) at the point that I've clicked inside the image.

    Is it possible? Can anyone just give me an example on how to do that?

    Thank you in advance,


  • Moderators

    you just need to map the mouse event's pos() from the widget which draws your image to image coordinates.
    The you can simply start a painter on it:
    @
    QPainter p(&pixmap);
    p.draw...(); //depending what you draw here you need to consider the mapped coordinates
    @



  • Thank you for your reply!

    Actually I tried almost everything that I found in the internet to draw a single point over an image using QMouseEvent, but nothing really worked.

    I have the following code:

    @
    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    static int counter = 0;

    MainWindow::MainWindow(QWidget parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    img = imread("/home/santiago/GGW.jpg");
    QImage qImage((uchar
    )img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
    ui->lblArea->setPixmap(QPixmap::fromImage(qImage));
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::MousePressed()
    {
    QString px = QString::number(ui->lblArea->x);
    QString py = QString::number(ui->lblArea->y);

    QString text = "X: " + px + " Y: " + py;
    
    if (counter < 6){
        x[counter] = ui->lblArea->x;
        y[counter] = ui->lblArea->y;
        ui->txtCoord->appendPlainText(text);
        ui->txtCoord->appendPlainText("Ok!");
        counter++;
        QPoint pt(x[counter], y[counter]);
        points.append(pt);
        update();
    }
    if (counter == 6)
        disconnect(ui->lblArea);
    

    }

    void MainWindow::on_btnStart_clicked()
    {
    x = new int[6];
    y = new int[6];
    connect(ui->lblArea, SIGNAL(Mouse_Pressed()), this, SLOT(MousePressed()));
    ui->txtCoord->appendPlainText("Start!");
    }

    void MainWindow::paintEvent(QPaintEvent *e)
    {
    QPainter painter(ui->lblArea);
    QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
    painter.setPen(pen);
    painter.drawPoint(x[counter], y[counter]);
    }
    @

    And

    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QtCore>
    #include <QtGui>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/core/core.hpp>
    #include <QVector>
    #include "myqlabel.h"

    using namespace cv;

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private slots:
    void MousePressed();

    void on_btnStart_clicked();
    

    protected:

    void paintEvent(QPaintEvent *e);
    

    private:
    Mat img;

    int *x, *y;
    int ii;
    QVector<QPoint> points;
    Ui::MainWindow *ui;
    

    };

    #endif // MAINWINDOW_H
    @

    @
    #include "myqlabel.h"

    myQLabel::myQLabel(QWidget *parent) :
    QLabel(parent)
    {
    }

    void myQLabel::mousePressEvent(QMouseEvent *ev)
    {
    this->x = ev->x();
    this->y = ev->y();
    emit Mouse_Pressed();
    }
    @

    @
    #ifndef MYQLABEL_H
    #define MYQLABEL_H

    #include <QLabel>
    #include <QMouseEvent>
    #include <QEvent>
    #include <QDebug>

    class myQLabel : public QLabel
    {
    Q_OBJECT
    public:
    explicit myQLabel(QWidget *parent = 0);

    void mousePressEvent(QMouseEvent *ev);
    
    int x, y;
    

    signals:

    void Mouse_Pressed();
    

    public slots:

    };

    #endif // MYQLABEL_H
    @

    What should I do to get the coordinates from QMouseEvent and draw a single point using QPainter?



  • Anyone, please?



  • Also, I want to limit the drawning area to the label area.


  • Moderators

    your MainWindow::paintEvent() doesn't work like you expect it would.
    Instead overrriding the paintEvent() handler in the main window override it in the label for example. But not even this is necessary.

    Check if this is all you need (remove the paintEvent form the mainWindow, etc.):

    @
    void myQLabel::mousePressEvent(QMouseEvent *event)
    {
    this->x = event->x();
    this->y = event->y();
    emit Mouse_Pressed();

    QPixmap pix = this->pixmap();
    if( ! pix.isNull() )
    {
        QPainter p(&pix);
            p.drawEllipse ( event->pos(), 2, 2 );
        p.end();
        this->setPixmap(pix);
    }
    QLabel::mousePressEvent(event);
    

    }
    @

    Do you want to limit the drawing also only on the image or on the whole label? meaning you could draw beside the image but still on the label?



  • I did exaclty what you saidm but I got the floowing error message:

    conversion from 'const QPixmap*' to non-scalar type 'QPixmap' requested

    Then, I tried this:

    @
    QPixmap *pix = new QPIxmap(this->pixmap());
    @

    but still getting error messages...


  • Moderators

    ok my fault ... sorry.

    Try this:
    @
    void myQLabel::mousePressEvent(QMouseEvent *event)
    {
    QPixmap pix;
    if( this->pixmap() && ! this->pixmap()->isNull() )
    pix = this->pixmap()->copy();
    else
    pix = QPixmap(this->size());

        QPainter p(&pix);
            p.drawEllipse ( event->pos(), 2, 2 );
        p.end();
        this->setPixmap(pix);
    
        QLabel::mousePressEvent(event);
    }
    

    @



  • Ok! Now it works!

    THANK YOU!!!

    But a new problem arises! When I click, the elipses are not placed where they were supposed to be...


  • Moderators

    yep the problem is that the label is bigger than the pixmap so the event coordinates (mapped to the label) doesn't match the pixmap.
    The easiest thing (without the calculations for the coordinate translateions) would be to ensure that the label is always the same size as the pixmap:
    @
    label->setFixedSize( pixmap.size() ); //call this every time you set a new image to the label
    @

    Then place the label in another widget for example.



  • After one week trying, now it is working!!!!!!!!!! THANK YOU!!!! :D :D :D \o/ \o/ \o/


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.