Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Qt. Detectar item al pasar el ratón sobre él

Estas en el tema de Qt. Detectar item al pasar el ratón sobre él en el foro de C/C++ en Foros del Web. Hola: Estaba investigando sobre QGraphicsScene y QGraphicsView, y no termino de enterarme de cómo hacer que al pasar el puntero del ratón sobre un QGraphicsItem ...
  #1 (permalink)  
Antiguo 11/08/2016, 01:58
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Qt. Detectar item al pasar el ratón sobre él

Hola:

Estaba investigando sobre QGraphicsScene y QGraphicsView, y no termino de enterarme de cómo hacer que al pasar el puntero del ratón sobre un QGraphicsItem éste haga algo.

Estas son las dos cosas que he intentado:

1.- En mi clase heredada de QGraphicsScene, implementar dentro de la función mouseMoveEvent la función itemAt(). De esta forma:

Código C++:
Ver original
  1. void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
  2. {
  3. .................
  4. if (itemAt(event->scenePos(),QTransform()))
  5.     {
  6.         qDebug()<<"Algo";
  7.     }
  8. }

Pero siempre que muevo el ratón me muestra "Algo"

2.- En un QGraphicsItem heredado implementar las funciones virtuales
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);


Así (para un objeto circulo heredado de un QGraphicsEllipseItem):

Código C++:
Ver original
  1. void micirculo::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
  2. {
  3.     this->setPen(QPen(Qt::yellow, 3, Qt::SolidLine));
  4.     qDebug()<<"Cambio a amarillo";
  5.     QGraphicsItem::hoverEnterEvent(event);
  6. }
  7.  
  8. void micirculo::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
  9. {
  10.     this->setPen(QPen(Qt::magenta, 3, Qt::SolidLine));
  11.     qDebug()<<"Cambio a rosa";
  12.     QGraphicsItem::hoverMoveEvent(event);
  13. }
  14.  
  15. void micirculo::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
  16. {
  17.     this->setPen(QPen(Qt::green, 3, Qt::SolidLine));
  18.     qDebug()<<"Cambio a verde";
  19.     QGraphicsItem::hoverLeaveEvent(event);
  20. }

En el QGraphicsView está activado el setMouseTracking:
Código C++:
Ver original
  1. view->setMouseTracking(true);

Y en la clase micirculo tengo esto en el constructor:
Código C++:
Ver original
  1. setAcceptHoverEvents(true);

Pero esto sólo funciona si presiono el botón del ratón sobre el objeto, y yo quiero que sea sólo al pasar el puntero sobre él

Saludos y gracias
__________________
Mi calculadora en Qt
  #2 (permalink)  
Antiguo 11/08/2016, 09:37
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Qt. Detectar item al pasar el ratón sobre él

Con respecto al primer modelo has de tener en cuenta que el QGraphicsSceneMouseEvent tiene varios métodos relacionados con la posición:
  • pos(), que devuelve una posición con respecto al item en el que se encuentren.
  • scenePos(), que devuelve una posición con respecto a la escena en la que te encuentres. Este es el que quieres usar.
  • screenPos(), que devuelve la posición con respecto a la pantalla en la que se ejecuta.

Resumen, cambia pos() por scenePos() y listo. No obstante, te dejo un widget básico que funcione de manera similiar

Código C++:
Ver original
  1. #include <QDebug>
  2.  
  3. #include <QGraphicsItem>
  4. #include <QGraphicsView>
  5. #include <QGraphicsScene>
  6. #include <QGraphicsSceneMouseEvent>
  7. #include <QGraphicsSimpleTextItem>
  8.  
  9. class xscene : public QGraphicsScene {
  10.   public:
  11.     explicit xscene(QWidget * parent = nullptr) : QGraphicsScene(parent) {
  12.       ui_text = new QGraphicsSimpleTextItem("Texto de prueba");
  13.       addItem(ui_text);
  14.     }
  15.   private:
  16.  
  17.     void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {
  18.       if (itemAt(event->scenePos(),QTransform()))
  19.         qDebug() << "Hay algo aquí";
  20.  
  21.       QGraphicsScene::mouseMoveEvent(event);
  22.     }
  23.  
  24.     QGraphicsSimpleTextItem* ui_text;
  25. };
  26.  
  27. class widget : public QGraphicsView
  28. {
  29.     Q_OBJECT
  30. public:
  31.     explicit widget(QWidget* parent = nullptr) : QGraphicsView(parent) {
  32.       setMouseTracking(true);
  33.       myScene = new xscene(this);
  34.       setScene(myScene);
  35.  
  36.     }
  37.  
  38. private:
  39.     xscene* myScene;
  40. };
  #3 (permalink)  
Antiguo 11/08/2016, 10:03
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Qt. Detectar item al pasar el ratón sobre él

En cuanto al segundo caso no sé exactamente cuál es el problema, a mí me funciona bien sin hacer click, te dejo un ejemplo similar a ver si puedes ver cual es tu problema. Saludos.

Código C++:
Ver original
  1. #include <QDebug>
  2.  
  3. #include <QGraphicsItem>
  4. #include <QGraphicsView>
  5. #include <QGraphicsScene>
  6. #include <QGraphicsSceneMouseEvent>
  7. #include <QGraphicsEllipseItem>
  8.  
  9. class xcircle : public QGraphicsEllipseItem {
  10.   public:
  11.     explicit xcircle(QGraphicsItem* parent = nullptr) : QGraphicsEllipseItem(parent) {
  12.       setAcceptHoverEvents(true);
  13.       setPen(QPen(Qt::green, 3, Qt::SolidLine));
  14.       setRect(40,40,100,100);
  15.  
  16.     }
  17.  
  18.   private:
  19.     void hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
  20.       setPen(QPen(Qt::yellow, 3, Qt::SolidLine));
  21.       qDebug()<<"Cambio a amarillo";
  22.       QGraphicsItem::hoverEnterEvent(event);
  23.     }
  24.  
  25.     void hoverLeaveEvent(QGraphicsSceneHoverEvent *event){
  26.       setPen(QPen(Qt::green, 3, Qt::SolidLine));
  27.       qDebug()<<"Cambio a verde";
  28.       QGraphicsItem::hoverLeaveEvent(event);
  29.     }
  30. };
  31.  
  32. class xscene : public QGraphicsScene {
  33.   public:
  34.     explicit xscene(QWidget * parent = nullptr) : QGraphicsScene(parent) {
  35.       ui_circle = new xcircle();
  36.       addItem(ui_circle);
  37.     }
  38.   private:
  39.     xcircle* ui_circle;
  40. };
  41.  
  42. class widget : public QGraphicsView
  43. {
  44.     Q_OBJECT
  45. public:
  46.     explicit widget(QWidget* parent = nullptr) : QGraphicsView(parent) {
  47.       setMouseTracking(true);
  48.       myScene = new xscene(this);
  49.       setScene(myScene);
  50.  
  51.     }
  52.  
  53. private:
  54.     xscene* myScene;
  55. };
  #4 (permalink)  
Antiguo 11/08/2016, 11:51
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Detectar item al pasar el ratón sobre él

Hola xKuZz:

Muchas gracias por responder.
Al final, sobre la forma 1, por un lado, realmente yo capturo el evento scenePos(). El problema era que tenía dibujada una cruceta que se mueve de forma solidaria con el puntero, y claro....siempre encontraba un item!

Aclarado esta parte, sigo sin saber por qué a mi no me funciona la cosa de forma correcta.

Ahora, desactivando el item de la cruceta, sólo me funciona si
1.- Tengo reimplementada la función mouseMoveEvent() en la subclase que deriva de QGraphicsScene
2.- Tengo reimplementados los métodos "Hover" en la subclase que deriva de QGraphicsEllipseItem.

Y encima de todo no va bien, ya que sólo reacciona al paso del puntero cuando toca otro widget, si no es así, es como si no hubiera pasado nada.


Miro y remiro tu código, que de todas formas es mas o menos como yo lo tengo, y no veo nada diferente.

Sólo se me ocurre que la forma en la que añado objetos a la escena pueda no ser la correcta. Me explico (y de paso pido ayuda por si este método no es muy correcto):

En la clase derivada de QGraphicsScene, tengo un puntero del tipo micirculo y a forma de añadir círculos a la Escena es:

-Al primer toque del ratón, creo el objeto micirculo a partir del puntero (implementado en mousePressEvent() de la clase derivada QGraphicsScene)
Algo como:
Código C++:
Ver original
  1. micirculo* c = new micirculo(event->scenePos());
  2. addItem(c);
-Al mover el ratón, y si hay un círculo, éste cambia el tamaño (implementado en mousePressEvent() de la clase derivada QGraphicsScene)
-Al volver a presionar el ratón, el puntero usado para crear el círculo apunta a nullptr de nuevo, quedándose el circulo creado con su tamaño definitivo y perteneciendo ahora a la escena (por eso entiendo que puedo volver a apuntar a nullptr ya que a partir de ahora ese objeto ya no depende del puntero sino de la escena)

En fin, sólo se me ocurre que este método de alguna forma impida el normal funcionamiento de las funciones del ratón (creo que estoy diciendo una tontería, pero como ya llevo dos días enredando con esto, me da por pensar cualquier cosa por absurda que sea)
__________________
Mi calculadora en Qt

Última edición por dehm; 11/08/2016 a las 12:02
  #5 (permalink)  
Antiguo 11/08/2016, 12:11
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Qt. Detectar item al pasar el ratón sobre él

No veo nada raro en lo que dices que hayas hecho, si puedes subir el código completo para que pueda echarle un vistazo quizá pueda echarte un cable.

Edit: Resiva haber llamado a QGraphicsScene::mouseMoveEvent(event) etc que antes en el ejemplo he visto que no lo has puesto y puede ser tu problema
  #6 (permalink)  
Antiguo 11/08/2016, 12:35
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Detectar item al pasar el ratón sobre él

Cita:
Iniciado por xKuZz Ver Mensaje
No veo nada raro en lo que dices que hayas hecho, si puedes subir el código completo para que pueda echarle un vistazo quizá pueda echarte un cable.

Edit: Resiva haber llamado a QGraphicsScene::mouseMoveEvent(event) etc que antes en el ejemplo he visto que no lo has puesto y puede ser tu problema
Era eso. Olvidé hacer la llamada a QGraphicsScene::mouseMoveEvent(event). Ahora todo va bien.

¡Gracias y marco el tema como solucionado!
__________________
Mi calculadora en Qt

Etiquetas: int, item
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:55.