I have the following code to set up a QGraphicsScene
. I wish to click on the scene and draw a point at the location I've clicked. How could I do this? This is my current code:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsScene *scene;
QGraphicsView *view = new QGraphicsView(this);
view->setGeometry(QRect(20, 50, 400, 400));
scene = new QGraphicsScene(50, 50, 350, 350);
view->setScene(scene);
}
UPDATE: There is a new class called QGraphicsSceneMouseEvent
that makes this a little easier.
I just finished an example using it here:
https://stackoverflow.com/a/26903599/999943
It differs with the answer below in that it subclasses QGraphicsScene
, not QGraphicsView
, and it uses mouseEvent->scenePos()
so there isn't a need to manually map coordinates.
You are on the right track, but you still have a little more to go.
You need to subclass QGraphicsView
to be able to do something with mouse presses or with mouse releases using QMouseEvent
.
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsEllipseItem>
#include <QMouseEvent>
class MyQGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
explicit MyQGraphicsView(QWidget *parent = 0);
signals:
public slots:
void mousePressEvent(QMouseEvent * e);
// void mouseReleaseEvent(QMouseEvent * e);
// void mouseDoubleClickEvent(QMouseEvent * e);
// void mouseMoveEvent(QMouseEvent * e);
private:
QGraphicsScene * scene;
};
QGraphicsView
doesn't natively have dimension-less points. You will probably want to use QGraphicsEllipse
item or simply, scene->addEllipseItem()
with a very small radius.
#include "myqgraphicsview.h"
#include <QPointF>
MyQGraphicsView::MyQGraphicsView(QWidget *parent) :
QGraphicsView(parent)
{
scene = new QGraphicsScene();
this->setSceneRect(50, 50, 350, 350);
this->setScene(scene);
}
void MyQGraphicsView::mousePressEvent(QMouseEvent * e)
{
double rad = 1;
QPointF pt = mapToScene(e->pos());
scene->addEllipse(pt.x()-rad, pt.y()-rad, rad*2.0, rad*2.0,
QPen(), QBrush(Qt::SolidPattern));
}
Note the usage of mapToScene()
to make the pos()
of the event map correctly to where the mouse is clicked on the scene.
You need to add an instance of your subclassed QGraphicsView
to the centralWidget's layout of your ui if you are going to use a form.
QGridLayout * gridLayout = new QGridLayout(ui->centralWidget);
gridLayout->addWidget( new MyQGraphicsView() );
or if your ui has a layout already it will look like this:
ui->centralWidget->layout()->addWidget( new MyGraphicsView() );
If you don't use a QMainWindow
and a form, you can add it to a QWidget
if you set a layout for it and then add your QGraphicsView
to that layout in a similar manner. If you don't want a margin around your QGraphicsView
, just call show on it and don't put it inside a different layout.
#include <QtGui/QApplication>
#include "myqgraphicsview.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyQGraphicsView view;
view.show();
return a.exec();
}
And that's it. Now you are dangerous with QGraphicsView
's and their interaction with the mouse.
Be sure to read and study about Qt's Graphics View Framework and the related examples to be effective when using QGraphicsView
and QGraphicsScene
. They are very powerful tools for 2D graphics and can have a bit of a learning curve but they are worth it.