2009-05-10 20 views
11

Soy relativamente nuevo en la programación con Qt y tenía una pregunta. Versión corta:Qt señales & herencia pregunta

¿Cómo heredo las señales definidas en las superclases?

Estoy intentando subclase de otra persona muy bien hechas QTWidgets para cambiar algunos de los comportamientos por defecto:

 

//Plot3D is a QWidget that defines a signal "rotationChanged" 
class matLinePlot : public QObject, public Plot3D { 

    Q_OBJECT; 
     //etc... 
public: 
     //etc... 

     //Catch Plot3D's signal "rotationChanged" and do some magic with it: 
    void initPlot(){ 
       QObject::connect(this, SIGNAL(rotationChanged(double , double , double)), 
      this, SLOT(myRotationChanged(double, double, double))); 
    } 
}; 

El problema está en el QObject :: conecta la línea. Lo que me gustaría hacer es conectar el rotationChanged SIGNAL (de qwt3D_plot.h) a una función local/SLOT - "myRotationChanged". Sin embargo cada vez que hago esto, en tiempo de ejecución consigo:

Object::connect: No such signal matLinePlot::rotationChanged(double, double, double)

en C: ... \ matrixVisualization.h. Por supuesto, sé que rotationChanged no está en matrixVisualization.h - está en qwt_plot3D.h, pero pensé que como heredo de Plot3D todo debería estar bien. Pero, ahora que lo pienso, dado que SIGNAL y SLOT son macros, supongo que MOC no sabe ni se preocupa por la herencia.

Lo que me lleva a mi pregunta, ya que MOC y SIGNALS/SLOTS no parecen saber acerca de la herencia, etc. ¿Cómo puedo crear una subclase de un widget definido en otro lugar y obtener acceso a las señales del widget?

Tengo muchos ejemplos de cómo usar la encapsulación para lograr algo como esto, pero me temo que no entiendo cómo hacerlo con la herencia.

Disculpe si esta es una pregunta ridícula - Siento que me falta algo obvio.

+1

La referencia que ve en el error de "matrizVisualización.h" muestra en qué archivo se encuentra el QObject :: connect fallido, no en dónde está tratando de "buscar" la señal correspondiente. –

Respuesta

9

Supongo que el problema es la herencia múltiple:

class matLinePlot : public QObject, public Plot3D 
... 

que asumen que Plot3D es una subclase de QObject? En este caso, debe hacer

class matLinePlot : public Plot3D 
... 

en su lugar.

+1

Eso hace que las cosas en un error de enlace: 1> moc_matrixVisualization.obj: error LNK2001: símbolo externo sin resolver "público: static struct const QMetaObject qwt3d :: :: plot3d staticMetaObject"? (StaticMetaObject @ @ plot3d qwt3d @@ @@ 2UQMetaObject B) El documento sugiere el uso de QT herencia múltiple: http://doc.trolltech.com/4.3/uitools-multipleinheritance.html Aunque se extienden Qwidget, necesito QObject. – Pete

+2

El enlace que ha publicado muestra un ejemplo sobre cómo usar archivos .ui (los archivos creados por Qt Designer). Una diferencia importante es que Ui :: CalculatorForm no es una subclase de QObject. La regla al crear subclases desde QObject (y usar herencia múltiple) es que solo una de las superclases puede ser un QObject y que QObject tiene que ser la primera parte en la herencia. – ashcatch

+1

el documento sugiere herencia múltiple en un escenario diferente. cuando uses Qt Designer obtendrás un archivo .ui, luego una herramienta llamada uic tomará ese archivo .ui y generará una clase que es básicamente una traducción del archivo .ui, solo en C++ real. entonces lo que básicamente sugieren es heredar de esa clase, en lugar de tenerlo como miembro. –

1

Creo que funcionará si la señal Plot3D :: rotationChanged es pública o está protegida. ¿Estás seguro de que la señal no es privada?

Editar:

Aunque no pude encontrar una referencia específica, voy a tener que concluir que las señales son siempre públicos. Al menos una prueba que hice aquí parecía indicar que podía conectarme a una señal incluso si estaba declarada en la sección privada de una clase.

También verifiqué que una señal declarada en QObject podría conectarse utilizando una subclase de QObject en la declaración de conexión, por lo que las señales son definitivamente heredables. Como veo en otras respuestas y comentarios aquí, el problema debe ser en otro lugar.

+0

Hola, He intentado poner una palabra clave pública antes de la palabra clave señal, pero Qt MOC no le gustó: 1> MOC incluyen \ qwt3d_plot.h 1> include \ qwt3d_plot.h (143): Error: las señales no pueden tiene especificador de acceso 1> Proyecto: error PRJ0019: Una herramienta devolvió un código de error de "MOC include \ qwt3d_plot.h" – Pete

+0

Vaya. Obviamente debería haber usado "public: signals:", pero eso no ha ayudado. – Pete

0

Incorrecto -> ver comentarios.

Estoy usando Qtopia en Uni y creo recordar que alguien dijo algo sobre el espaciado en los parámetros SIGNAL y SLOT para conectarse.

trate de usar

QObject::connect(this, SIGNAL(rotationChanged(double,double,double)), 
      this, SLOT(myRotationChanged(double,double,double))); 

Sé que no parece intuitiva, como C++ no es sensible a los espacios en blanco, sin embargo creo que tiene algo que ver con un poco de la magia que Qtopia/QT utiliza cuando conectando señales y ranuras. Esto puede aplicarse solo a Qtopia, o puedo haber escuchado mal, pero inténtalo. Además, ¿las señales son públicas o están protegidas y ha incluido los archivos de encabezado apropiados?

+0

Ahora tengo: público: señales: \t \t //! Emitido, si se cambia la rotación rotación de vacíoCambiado (doble xAngle, doble yAngulo, doble zAngulo); En la cabecera y la biblioteca de trazado, y QObject :: conectar (esto, la señal (rotationChanged (doble, doble, doble)), \t \t esto, SLOT (myRotationChanged (doble, doble, doble))); En mi clase derivada ... sigue el mismo error. He incluido el encabezado: #include // tiene Plot3D clase – Pete

+0

Cuando declara las señales, no declare un nombre para el parámetro, solo los tipos. Eso es public: señales: rotación de vacíoCambiado (doble, doble, doble); Esperemos que eso solucione su error. – mdec

+0

El espaciado no afecta a las señales ni a las ranuras, lo que se escucha es la normalización de la señal/ranura, que poco acelera el código, pero eso no se nota de ninguna manera. – ismail

2

SIGNAL (x) y SLOT (x) son macros que generan cadenas literales. En el tiempo de ejecución, las ranuras y las señales se combinan utilizando cadenas comparadas de esos literales generados.

(Me hubiera añadido un comentario al comentario de mdec, pero no tengo representante suficiente)

+0

Correcto, creo que ese es el meollo de este problema; debido a que la cadena que coincide con el combo MACRO/MOC solo busca en el archivo de encabezado actual de la señal, no sabe buscar en mi otra biblioteca de código compilado. – Pete

+0

Pete, estoy bastante seguro de que estás equivocado. Las señales y las ranuras se guardan en algún lugar (moc genera el código para esto, puede verlo en el archivo * _moc), no tiene nada que ver con el archivo de encabezado actual. –

+0

(¡maldiciones! - No tengo suficientes representantes para agregar al último comentario de Pete sobre el error de enlace) Parece que no está enlazando en moc_qwt3D_plot.cpp. –

Cuestiones relacionadas