2014-02-26 24 views
0

我有一個圖像存儲在場景中的Qlabel。我想讓Qlabel圖像跟隨光標在場景中移動的位置。我試過QGraphicsSceneMouseMove,還沒有接近。如何讓qlabel跟隨光標在場景中

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

    } 

回答

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。我認爲當鼠標事件的信息很方便時,這是一種非常全面的鼠標查找方式。如果你做了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()獲得可能匹配的座標。

How to draw a point (on mouseclick) on a QGraphicsScene?

在QWidget中的POS財產,你move()通常修改。 setGeometry也有效,但您最終還是會參考widthheight很多。

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,但仍然沒有移動。 – user3353931

+0

非常棒!但我正在考慮讓qwidget保持靜止並指向光標方向。 – user3353931

+0

像有一個箭頭指向光標?就像一場遊戲中的固定潮流,它將目標上的加農炮畫出來? – phyatt

相關問題