كيفية الحصول على qlabel لمتابعة المؤشر في المشهد
سؤال
لدي صورة مخزنة في 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());
}
امل ان يساعد.