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

Qt. Capturar información desde un widget

Estas en el tema de Qt. Capturar información desde un widget en el foro de C/C++ en Foros del Web. Hola, con motivo de la duda sobre capturar eventos de teclado, estaba trasteando para ver si podía capturar un evento del ratón en un widget ...
  #1 (permalink)  
Antiguo 31/08/2015, 04:03
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Qt. Capturar información desde un widget

Hola, con motivo de la duda sobre capturar eventos de teclado, estaba trasteando para ver si podía capturar un evento del ratón en un widget y leerlo fuera de él.
Y ya de paso, tengo otra duda, y es que no sé cómo reimplementar una función virtual en un widget puesto desde Qt Designer.

Como me explico tan mal, voy a intentar ilustrarlo:

Sobre la segunda duda, digamos que me creo un QGraphicsView dentro de un QWidget.

Pero ahora no sé cómo acceder a sus miembros para reimplementar la función:
void mousePressEvent (QMouseEvent* m_evento);, así que sólo se me ocurre crear una clase que herede de QGraphicsView y en esa clase reimplementar la función.

A su vez eso me obliga a no poder poner directamente el widget en Qt Designer, sino a tener que promocionarlo. No es que pase nada malo, pero no sé si es el método correcto.

Esta sería la clase:

Código C++:
Ver original
  1. class VentanaGrafica : public QGraphicsView
  2. {
  3.     Q_OBJECT
  4. public:
  5.     explicit VentanaGrafica(QWidget *parent = 0);
  6.     void mousePressEvent (QMouseEvent* m_evento);
  7. ..................

Y lo que habría en Qt Designer es un QWidget dentro de otro promocionado a VentanaGrafica.

Y la otra duda, es que ahora yo capturo la posición del ratón dentro de la VentanaGrafica, pero.....¿como puedo llevar esa información fuera de ella?

Como siempre, saludos y gracias!
__________________
Mi calculadora en Qt
  #2 (permalink)  
Antiguo 31/08/2015, 04:35
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Qt. Capturar información desde un widget

Cita:
Iniciado por dehm Ver Mensaje
Pero ahora no sé cómo acceder a sus miembros para reimplementar la función:
void mousePressEvent (QMouseEvent* m_evento);, así que sólo se me ocurre crear una clase que herede de QGraphicsView y en esa clase reimplementar la función.
La magia de la encapsulación, si un método es privado o protegido no podrás acceder al mismo desde fuera de la clase. Únicamente si el método es protegido entonces podrás reimplementarlo al tirar de herencia.

Sin este tipo de protecciones realizar programas grandes sería un auténtico caos.

Cita:
Iniciado por dehm Ver Mensaje
A su vez eso me obliga a no poder poner directamente el widget en Qt Designer, sino a tener que promocionarlo. No es que pase nada malo, pero no sé si es el método correcto.
Actualmente hay dos formas de utilizar widgets personalizados con el QtDesigner:

  • Promocionar los objetos
  • Crear un plugin
En el primer caso, el más facil de usar, en vez de componer la ventana usando nuestro widget personalizado hacemos el maquetado usando un widget padre. Este maquetado es meramente visual, ya que el código C++ que se genera intentará crear nuestro widget directamente. La principal ventaja de este mecanismo es la simplicidad de uso, mientras que la desventaja es que QtDesigner no conoce todas las características de nuestro widget, por lo que no podremos configurar todas sus propiedades usando el editor y tendremos que hacerlo a mano.

En el segundo caso tendremos que currarnos un plugin y compilarlo para generar una DLL. Hay que decir que el plugin no es de diseño libre, hay que heredar de ciertas clases para que nuestro plugin sea capaz de hablar el mismo idioma que QtDesigner. La finalidad de este plugin es brindar al editor un mecanismo a partir del cual sea capaz de conocer todos los detalles de nuestro widget (lista de propiedades, slots, señales, etc). Finalmente el plugin debemos pegarlo en una carpeta determinada y, al reiniciar QtDesigner, veremos nuestro widget en la barra de widgets. Si por alguna razón en el futuro nuestro widget cambia tendremos que actualizar el plugin o QtDesigner podría empezar a tener un comportamiento errático. La ventaja de este sistema es que podemos configurar nuestro widget con total libertad... la mayor desventaja es el coste en tiempo necesario para programar y mantener el plugin.

Cualquiera de los dos mecanismos son igualmente válidos. A mi personalmente me parece más cómodo tirar de promoción salvo que el widget vaya a tener un uso intensivo en mis aplicaciones.

Cita:
Iniciado por dehm Ver Mensaje
Esta sería la clase:

Código C++:
Ver original
  1. class VentanaGrafica : public QGraphicsView
  2. {
  3.     Q_OBJECT
  4. public:
  5.     explicit VentanaGrafica(QWidget *parent = 0);
  6.     void mousePressEvent (QMouseEvent* m_evento);
  7. ..................
Un par de incisos al respecto:

1. En C++11 se añadió nullptr. Esta nueva palabra permite indicar un puntero nulo. '0' así a secas puede ser interpretado también como un entero, lo cual puede acabar generando problemas. Un ejemplo:

Código C++:
Ver original
  1. void func( int*)
  2. { cout << "puntero" << endl; }
  3.  
  4. void func( int )
  5. { cout << "entero" << endl; }
  6.  
  7. int main( )
  8. {
  9.   int* variable;
  10.  
  11.   // imagina 20 lineas de codigo aqui en medio
  12.  
  13.   variable = 0; // variable era un entero o un puntero?
  14.   variable = nullptr; // seguro que variable es un puntero
  15.  
  16.   // Estas dos lineas las pongo para evitar errores de ejecución
  17.   int dummy;
  18.   variable = &dummy;
  19.  
  20.   func( variable); // puntero
  21.   func( *variable); // entero
  22.   func( 0 ); // ¿puntero? ¿entero? Solución: entero
  23.   func( (int*)0 ); // puntero (un poco chapucero)
  24.   func( static_cast<int*>(0) ); // puntero (más estándar pero con verborrea)
  25.   func( nullptr ); // puntero
  26. }

Mi consejo es desterrar poco a poco tanto '0' como NULL para hacer asignaciones o comparaciones con punteros y usar nullptr en su lugar. Es más seguro.

2. C++11 también introdujo la palabra reservada override. Esta palabra se usa al final de los métodos de una clase y obliga al compilador a comprobar que ese método sobreescribe a algún método de las clases padre. Si el compilador no encuentra un método al que sobreescribir se producirá un error de compilación.

Esta palabra reservada es muy util, ya que si, por ejemplo, editas el padre y cambias la firma de la función (o si editas el hijo y sin darte cuenta la firma cambia), la compilación fallará y te darás cuenta del error.

Antes de la existencia de esta palabra clave estos errores podían ser un auténtico quebradero de cabeza, ya que sin errores de por medio, depurar este tipo de problemas suele requerir bastante tiempo.

Y, como no podía ser de otra forma, un ejemplo para ilustrarnos:

Código C++:
Ver original
  1. class Padre
  2. {
  3.   public:
  4.     virtual int func1( int );
  5.     virtual int func2( char, int );
  6.     virtual int func3( string );
  7.     int func4( int );
  8. };
  9.  
  10. class Hija : public Padre
  11. {
  12.   public:
  13.  
  14.   int func1( ); // No estamos sobreescribiendo sino sobrecargando... OJO!!!
  15.  
  16.   int func2( int, char ) override; // ERROR: Los parametros estan desordenados
  17.  
  18.   int func3( string ) override; // OK
  19.  
  20.   int func4( int ) override; // ERROR: func4 en el padre no es virtual y no se puede sobreescribir
  21. };

Cita:
Iniciado por dehm Ver Mensaje
Y la otra duda, es que ahora yo capturo la posición del ratón dentro de la VentanaGrafica, pero.....¿como puedo llevar esa información fuera de ella?
Pues depende de las necesidades del código:

  • Puedes lanzar una señal que crees para la ocasión
  • Puedes hacer uso de un patrón de diseño para avisar a los cliente.
  • Puedes almacenar los valores en una lista y devolver dicha lista con un método
Cada mecanismo tiene sus ventajas y sus inconvenientes, dependiendo de las necesidades de tu código te interesará más usar un mecanismo u otro.


Un saludo.

Última edición por eferion; 31/08/2015 a las 04:45
  #3 (permalink)  
Antiguo 31/08/2015, 15:05
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Capturar información desde un widget

eferion, no tengo palabras. No sólo respondes perfectamente a la duda sino que amplias con más información que al menos para mi es oro en paño.

No pongo el solucionado por si todavía me pierdo intentando leer las coordenadas del ratón fuera de la clase. El caso es que mi primera idea fue la de crear una señal. Seguiré por ahí e intentaré poner el código.

Lo dicho, no sabes el lujo que es tenerte en el foro.
__________________
Mi calculadora en Qt

Etiquetas: int
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 21:08.