How to draw QRubberBand on a QGraphicsView using Mouse?

269 Views Asked by At

I have my MainWindow with a GraphicsView on which I want to draw a QRubberBand using MouseEvents. Therefore I created a custom GraphicsView class where I have the MouseEvents, however since I am a beginner, I don't know how to connect everything to the MainWindow.

Here's what I got so far:

mousegraphics.h (custom)

#ifndef MOUSEGRAPHICS_H
#define MOUSEGRAPHICS_H

#include <QGraphicsView>
#include <QWidget>
#include <QMainWindow>
#include <QRubberBand>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QEvent>

class MouseGraphics : public QGraphicsView
{
public:
    MouseGraphics(QWidget* parent = nullptr);

public slots:
    void mousePressEvent(QMouseEvent* e);
    void mouseMoveEvent(QMouseEvent* e);
    void mouseReleaseEvent(QMouseEvent* e);

private:
    QRubberBand* rb = nullptr;

    // Coordinates
    QPoint origin, dest;
};

#endif // MOUSEGRAPHICS_H



mousegraphics.cpp

#include "mousegraphics.h"

MouseGraphics::MouseGraphics(QWidget* parent) : QGraphicsView(parent)
{
    
}


void MouseGraphics::mousePressEvent(QMouseEvent *e)
{
    origin = e->pos();

    if(!rb)
    {
        rb = new QRubberBand(QRubberBand::Line, this);
    }

    rb->setGeometry(QRect(origin, QSize()));
    rb->show();
}

void MouseGraphics::mouseMoveEvent(QMouseEvent *e)
{
    rb->setGeometry(QRect(origin, e->pos()).normalized());
}

void MouseGraphics::mouseReleaseEvent(QMouseEvent *e)
{
    rb->hide();
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QRubberBand>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QEvent>

#include "mousegraphics.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

1

There are 1 best solutions below

0
On

you should create one class that inherits from QGraphicsView.

because you need mousePressEvent ,mouseReleaseEvent , mouseMoveEvent of QGraphicsView.

Then in MainWindow, you need one QGraphicsScene object and I create one QGridLayout and with the addWidget function add my QGraphicsView object to MainWindow UI.

So I do this :

In graphicsview.h:

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

#include <QGraphicsView>
#include <QObject>
#include <QRubberBand>

class graphicsView: public QGraphicsView
{
public:
    graphicsView();

protected:
    void  mousePressEvent(QMouseEvent *event);

    void  mouseReleaseEvent(QMouseEvent *event);

    void  mouseMoveEvent(QMouseEvent *event);

private:
    QRubberBand *rubberBand = nullptr;
    QPoint       origin;
};

#endif // GRAPHICSVIEW_H

graphicsview.cpp :

#include "graphicsview.h"

#include <QMouseEvent>
#include <QRect>

graphicsView::graphicsView()
{
}

void  graphicsView::mousePressEvent(QMouseEvent *event)
{
    origin = event->pos();

    if (!rubberBand)
    {
        rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    }

    rubberBand->setGeometry(QRect(origin, QSize()));
    rubberBand->show();
}

void  graphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    rubberBand->hide();
}

void  graphicsView::mouseMoveEvent(QMouseEvent *event)
{
    rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}

In mainwindow.h :

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow: public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);

    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

In mainwindow.cpp :

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

#include <QGraphicsScene>
#include <QGridLayout>
#include "graphicsview.h"

MainWindow::MainWindow(QWidget *parent):
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QGridLayout *gridLayout;

    gridLayout = new QGridLayout(centralWidget());
    gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
    auto          scene = new QGraphicsScene(this);
    graphicsView *_view = new graphicsView();
    _view->setScene(scene);

    gridLayout->addWidget(_view);
}

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

The result is this

enter image description here: