как заставить qlabel следовать за курсором в сцене

0

У меня есть изображение, сохраненное в Qlabel в сцене. Я хочу получить изображение Qlabel, чтобы следовать за ним, когда курсор перемещается внутри сцены. Я пробовал QGraphicsSceneMouseMove и еще не подошел.

    void scene::mouseMoveEvent(QGraphicsSceneMouseEvent /*mouseEvent*/)
    {

        QPointF P1 = ui->tankarmplay1->mapFromParent(QCursor.pos()); 
        int x = P1.x();
        int y = P1.y();
        ui->tankarmplay1->setGeometry(x,y, 50, 50);

    }
Теги:
qt
cursor
qlabel

1 ответ

1
Лучший ответ

UPDATE: добавлен QGraphicsLineItem который указывает на мышь. Это может быть заменено полным рисунком какой-то башни с использованием QGraphicsItemGroup и использованием того же вычисления вращения.

Следующие ссылки говорят о многом, о чем вы должны знать:

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

Я лично не использовал QCursor. Я думаю, что это очень окольный способ найти о мыши, когда у вас есть событие мыши pos информации под рукой. Если вы сделали QCursor, вам, вероятно, понадобится использовать mapFromGlobal не mapFromParent.

http://qt-project.org/doc/qt-5/qcursor.html#details

http://qt-project.org/doc/qt-5/qcursor.html#pos

Вот что я написал перед использованием конкретных методов QGraphicsSceneMouseEvent.

Чтобы заставить их работать, мне пришлось использовать mapToScene() чтобы, вероятно, совпадение координат.

Как нарисовать точку (на mouseclick) на QGraphicsScene?

В свойстве pos QWidget вы обычно изменяете его с помощью move(). setGeometry также работает, но вы также в конечном итоге ссылаетесь на width и height.

http://qt-project.org/doc/qt-4.8/qwidget.html#pos-prop

http://qt-project.org/doc/qt-4.8/qwidget.html#mouseTracking-prop

ОБНОВЛЕНИЕ: Удивительный пример, который показывает отслеживание мыши, используемое в сцене и вне сцены. Примечание. Использование QGraphicsTextItem, вероятно, будет более чистым, чем использование QLabel + QGraphicsProxyWidget для перемещения некоторого текста вокруг сцены.

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());
}

Надеюсь, это поможет.

  • 0
    phyatt, функция move () тоже не работает. Я установил true для MouseTracking, когда впервые создал сцену, но все еще не двигался.
  • 0
    Работает отлично! Но я смотрел, чтобы qwidget оставался неподвижным и указывал направление курсора.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню