UPDATE: Added a QGraphicsLineItem that points at the mouse. This could be replaced by a full drawing of a turret of some sort using a QGraphicsItemGroup, and using the same rotation calculation.
The following links talks about a lot of the things you should be familiar with:
http://qt-project.org/doc/qt-5/graphicsview.html
http://qt-project.org/doc/qt-5/application-windows.html
void scene::mouseMoveEvent(QGraphicsSceneMouseEvent * e /*mouseEvent*/)
{
// QPointF P1 = (e->pos());
// int x = P1.x();
// int y = P1.y();
// ui->tankarmplay1->setGeometry(x, y, 50, 50);
ui->tankarmplay1->move((int) e->pos().x(), (int) e->pos().y());
}
http://qt-project.org/doc/qt-5/qgraphicsscenemouseevent.html#pos
I haven't personally used QCursor. I think it is a very round-about way of finding about the mouse when you have the mouse event's pos information handy. If you did you QCursor, you would probably need to use mapFromGlobal not mapFromParent.
http://qt-project.org/doc/qt-5/qcursor.html#details
http://qt-project.org/doc/qt-5/qcursor.html#pos
Here is something I wrote up before using the specific QGraphicsSceneMouseEvent methods.
To get those to work I had to use mapToScene() to get the coordinates to probably match.
How to draw a point (on mouseclick) on a QGraphicsScene?
In the pos property of QWidget, you modify it with move() usually. setGeometry also works, but you also end up referencing the width and height a lot.
http://qt-project.org/doc/qt-4.8/qwidget.html#pos-prop
http://qt-project.org/doc/qt-4.8/qwidget.html#mouseTracking-prop
UPDATE: Awesome example that shows mouse tracking used in the scene and outside the scene
Note, using a QGraphicsTextItem would probably be cleaner than using a QLabel + QGraphicsProxyWidget to move some text around in the scene.
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFrame>
#include <QLabel>
#include <QPointF>
#include "mygraphicsscene.h"
#include <QGraphicsView>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
qreal map(const qreal & x1, qreal x, const qreal & x2, const qreal & y1, const qreal & y2);
public slots:
void on_sceneMouseMove(QPointF);
private:
QLabel * m_label;
MyGraphicsScene * m_scene;
QGraphicsView * m_view;
QFrame * m_labelContainer;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QGraphicsView>
#include "mygraphicsscene.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout * vbox = new QVBoxLayout;
m_view = new QGraphicsView;
m_scene = new MyGraphicsScene;
m_view->setScene(m_scene);
m_view->setMouseTracking(true);
m_scene->setSceneRect(-300,-300, 600, 600);
m_view->fitInView(m_scene->sceneRect());
vbox->addWidget(m_view, 1);
m_labelContainer = new QFrame;
m_labelContainer->setFrameShape(QFrame::Box);
m_label = new QLabel("Tracking Label");
m_labelContainer->setFixedSize(300, 300);
m_label->setParent(m_labelContainer);
vbox->addWidget(m_labelContainer, 1);
QObject::connect(m_scene, SIGNAL(mouseMoved(QPointF)),
this, SLOT(on_sceneMouseMove(QPointF)));
this->setLayout(vbox);
}
void Widget::on_sceneMouseMove(QPointF pt)
{
QPointF pt2;
pt2.setX(map(m_scene->sceneRect().left(), pt.x(), m_scene->sceneRect().right(),
m_labelContainer->rect().left(), m_labelContainer->rect().right()));
pt2.setY(map(m_scene->sceneRect().top(), pt.y(), m_scene->sceneRect().bottom(),
m_labelContainer->rect().top(), m_labelContainer->rect().bottom()));
// qDebug() << pt << pt2 << m_scene->sceneRect() << m_labelContainer->rect();
m_label->move(pt2.x(), pt2.y());
// m_label->setGeometry(pt.x(), pt.y(),
// m_label->width(), m_label->height());
}
qreal Widget::map(const qreal & x1, qreal x, const qreal & x2, const qreal & y1, const qreal & y2)
{
if(x < x1)
x = x1;
if(x > x2)
x = x2;
return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
}
Widget::~Widget()
{
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
mygraphicsview.h
#ifndef MYGRAPHICSSCENE_H
#define MYGRAPHICSSCENE_H
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsProxyWidget>
#include <QGraphicsLineItem> // Added this
class MyGraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit MyGraphicsScene(QObject *parent = 0);
signals:
void mouseMoved(QPointF);
public slots:
void mouseMoveEvent(QGraphicsSceneMouseEvent * );
private:
QGraphicsProxyWidget * m_labelProxy;
QGraphicsLineItem * m_lineItem; // Added this
};
#endif // MYGRAPHICSSCENE_H
mygraphicsview.cpp
#include "mygraphicsscene.h"
#include <QDebug>
#include <QLabel>
#include <QVector2D>
#include <qmath.h>
#include <QLineF>
MyGraphicsScene::MyGraphicsScene(QObject *parent) :
QGraphicsScene(parent)
{
QLabel * label = new QLabel("Tracking Widget\n in Scene");
m_labelProxy = this->addWidget(label);
// added the lines below to setup an item, pointing in the positive x direction
int x1 = 0;
int y1 = 0;
m_lineItem = new QGraphicsLineItem(x1, y1, x1 + 20, y1);
// m_lineItem->setTransformOriginPoint(x1, y1);
this->addItem(m_lineItem);
m_lineItem->setPos(-100, -100);
}
void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * e)
{
// qDebug() << e->pos() << e->screenPos() << e->scenePos();
emit mouseMoved(e->scenePos());
m_labelProxy->setPos(e->scenePos());
// Added these lines below to calculate and set the rotation.
// QVector2D v;
// v.setX(e->scenePos().x() - m_lineItem->pos().x());
// v.setY(e->scenePos().y() - m_lineItem->pos().y());
// m_lineItem->setRotation(qAtan2(v.y(), v.x())*180./(3.1459));
QLineF line(m_lineItem->pos(), e->scenePos());
m_lineItem->setRotation(360 - line.angle());
}
Hope that helps.