Cita:
Iniciado por dehm 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 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 Esta sería la clase:
Código C++:
Ver originalclass VentanaGrafica : public QGraphicsView
{
Q_OBJECT
public:
explicit VentanaGrafica(QWidget *parent = 0);
void mousePressEvent (QMouseEvent* m_evento);
..................
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 originalvoid func( int*)
{ cout << "puntero" << endl; }
void func( int )
{ cout << "entero" << endl; }
int main( )
{
int* variable;
// imagina 20 lineas de codigo aqui en medio
variable = 0; // variable era un entero o un puntero?
variable = nullptr; // seguro que variable es un puntero
// Estas dos lineas las pongo para evitar errores de ejecución
int dummy;
variable = &dummy;
func( variable); // puntero
func( *variable); // entero
func( 0 ); // ¿puntero? ¿entero? Solución: entero
func( (int*)0 ); // puntero (un poco chapucero)
func( static_cast<int*>(0) ); // puntero (más estándar pero con verborrea)
func( nullptr ); // puntero
}
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 originalclass Padre
{
public:
virtual int func1( int );
virtual int func2( char, int );
virtual int func3( string );
int func4( int );
};
class Hija : public Padre
{
public:
int func1( ); // No estamos sobreescribiendo sino sobrecargando... OJO!!!
int func2( int, char ) override; // ERROR: Los parametros estan desordenados
int func3( string ) override; // OK
int func4( int ) override; // ERROR: func4 en el padre no es virtual y no se puede sobreescribir
};
Cita:
Iniciado por dehm 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.