2012-02-23 22 views
7

Estoy intentando codificar una función de devolución de llamada estática que se llama con frecuencia de otra función estática dentro de la misma clase. Mi función de devolución de llamada necesita una señal emit pero por alguna razón simplemente no lo hace. Lo puse bajo un depurador y nunca se llama al slot. Sin embargo, cuando coloco el código que utilicé para emit funciona la información en una función no estática. ¿Hay alguna razón por la que no pueda emitir una señal desde una función estática? Intenté declarar una nueva instancia de la clase y llamar a la función de emisión, pero sin suerte.Señal de envío del método de clase estática en Qt

class Foo 
{ 
signals: 
    emitFunction(int); 
private: 
    static int callback(int val) 
    { 
     /* Called multiple times (100+) */ 
     Foo *foo = new Foo; 
     foo.emitFunction(val); 
    } 
    void run() 
    { 
     callback(percentdownloaded); 
    } 
}; 

He publicado un código básico que demuestra lo que estoy intentando hacer. Publicare el código completo a pedido.

Editar: Estoy posteando el código completo ya que es una especie de situación extraña. http://pastebin.com/6J2D2hnM

+1

¿Dónde conectar la señal y la ranura? – Nobody

+0

Los conecto en un archivo '.cpp' separado que se llama al presionar un botón. 'void MainWindow :: on_pushButton_clicked() { tProc = new Foo (this); connect (tProc, SIGNAL (ValChanged (int)), esto, SLOT (onNumberChanged (int))); tProc-> start(); } 'luego crea una nueva instancia de mi clase' Foo' e inicia el hilo que llama a la función de devolución de llamada. – user99545

+0

En su función de devolución de llamada estática, crea una nueva instancia de Foo y llama la señal sobre ella. Supongo que este es el punto donde quieres emitir la señal. ¿Cómo se conecta esta instancia a la ranura que desea abordar? – Nobody

Respuesta

10

Eso no va a funcionar, porque está creando un nuevo Foo cada vez que ingresa a esa función estática, y no conecta una señal a una ranura.

Por lo tanto, la solución sería la de pasar el objeto a esa función:

class Foo 
{ 
signals: 
    emitFunction(int); 
private: 
    static int callback(int val, Foo &foo) 
    { 
     /* Called multiple times (100+) */ 
     foo.emitFunction(val); 
    } 
    void run() 
    { 
     callback(percentdownloaded, *this); 
    } 
}; 

Otra opción es utilizar postEvent, pero yo no lo recomendaría.


Como no se puede modificar la firma de devolución de llamada, puede hacerlo de esta manera:

class Foo 
{ 
signals: 
    emitFunction(int); 
private: 
    static int callback(int val) 
    { 
     /* Called multiple times (100+) */ 
     theFoo->emitFunction(val); 
    } 
    static Foo *theFoo; 
    void run() 
    { 
     callback(percentdownloaded, *this); 
    } 
}; 

pero tendrá que inicializar la variable estática en alguna parte.

+0

Esto funcionaría, pero el problema es que mi función de devolución de llamada estática está siendo llamada por otra función que es de la librería libCURL y no puedo pasarle argumentos. No estoy seguro de cómo implementar su método en este caso. – user99545

+1

@ user99545 ​​agrega una variable estática, que se usa en la devolución de llamada. Voy a editar la respuesta –

+0

Gracias. Terminé usando su variable estática y la inicialicé pasando la instancia de la clase actual como un parámetro al hilo. Usé ese parámetro para inicializar la clase y funcionó. – user99545

0

Debe proporcionar un puntero a la instancia de la clase para que funcione.

Sin embargo, tenga en cuenta que, en general, no se recomienda emitir señales desde funciones estáticas. Las funciones estáticas se pueden invocar sin crear una instancia de la clase, lo que significa que (si no proporciona como argumento al emisor y lo usa explícitamente), no tendrá un objeto "emisor" para las señales emitidas.

Para estos casos, como sugiere Lol4t0, también prefiero las devoluciones de llamada.

2

en caso de que alguien aún encuentre la solución, esto es lo que hice, funciona en mi proyecto. 1. Asegúrese de que su clase sea un producto único 2. En función estática CB, emitFunction carga de la clase Singleton

static int callback(int val) 
    { 
    /* Called multiple times (100+) */ 
    MYClass::getInstance()->emitFunction(val); 
    } 
+0

buen enfoque y simple, incluso es seguro para subprocesos ya que la señal de emisión es. +1 – g24l

Cuestiones relacionadas