كيفية الحصول على qlabel لمتابعة المؤشر في المشهد

StackOverflow https://stackoverflow.com//questions/22030446

  •  21-12-2019
  •  | 
  •  

سؤال

لدي صورة مخزنة في 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);

    }
هل كانت مفيدة؟

المحلول

تحديث:تمت إضافة أ 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() للحصول على الإحداثيات التي ربما تتطابق.

كيفية رسم نقطة (عند النقر بالماوس) على 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 لتحريك بعض النصوص في المشهد.

القطعة. ح

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

امل ان يساعد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top