2012-02-23 11 views
7

Próbuję kodować statyczną funkcję zwrotną, która jest często wywoływana z innej funkcji statycznej w obrębie tej samej klasy. Moja funkcja oddzwaniania musi mieć sygnał, ale z jakiegoś powodu po prostu tego nie robi. Podłączyłem go do debuggera i slot nigdy nie jest wywoływany. Jednak po umieszczeniu kodu użyłem do emit danych w funkcji niestatycznej działa. Czy istnieje powód, dla którego nie mogę emitować sygnału z funkcji statycznej? Próbowałem zadeklarować nową instancję klasy i wywołać funkcję emitującą, ale bez powodzenia.Wysyłanie sygnału z metody klasy statycznej w 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); 
    } 
}; 

Mam opublikowany podstawowy kod, który pokazuje, co próbuję zrobić. Będę pisać pełny kod na życzenie.

Edytuj: Publikuję pełny kod, ponieważ jest to rodzaj dziwnego scenariusza. http://pastebin.com/6J2D2hnM

+1

Gdzie można podłączyć sygnał i SLOT? – Nobody

+0

Łączę je w osobnym pliku '.cpp', który wywoływany jest przez naciśnięcie przycisku. 'void MainWindow :: on_pushButton_clicked() { tProc = new Foo (this); connect (tProc, SIGNAL (ValChanged (int)), to, SLOT (onNumberChanged (int))); tProc-> start(); } 'następnie tworzy nowe wystąpienie mojej klasy' Foo' i uruchamia wątek, który wywołuje funkcję zwrotną. – user99545

+0

W swojej statycznej funkcji wywołania zwrotnego tworzysz nową instancję Foo i wywołujesz sygnał na niej. Przypuszczam, że jest to punkt, w którym chcesz emitować sygnał. Jak połączyć to wystąpienie z gniazdem, które chcesz rozwiązać? – Nobody

Odpowiedz

10

To nie zadziała, ponieważ za każdym razem, gdy wchodzisz w funkcję statyczną, tworzysz nowego Foo i nie podłączasz sygnału do gniazda.

więc poprawka byłoby przekazać obiekt do tej funkcji:

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); 
    } 
}; 

Inną opcją jest użycie postEvent, ale nie polecam go.


Ponieważ nie można zmodyfikować podpis oddzwonienia, można zrobić to tak:

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); 
    } 
}; 

ale musisz zainicjować zmienną statyczną, że gdzieś.

+0

To zadziała, ale problem polega na tym, że moja statyczna funkcja wywołania zwrotnego jest wywoływana przez inną funkcję pochodzącą z biblioteki libCURL i nie mogę przekazywać do niej argumentów. Nie jestem pewien, jak wdrożyć twoją metodę w tym przypadku. – user99545

+1

@ user99545 ​​dodaj zmienną statyczną, która jest używana w wywołaniu zwrotnym. Będę edytować odpowiedź –

+0

Dzięki. W końcu użyłem twojej zmiennej statycznej i zainicjowałem ją, przekazując bieżącą instancję klasy jako parametr do wątku. Użyłem tego parametru do zainicjowania klasy i zadziałało. – user99545

0

Musisz podać wskaźnik do instancji klasy, aby to działało.

Należy jednak zauważyć, że generalnie nie zaleca się emitowania sygnałów z funkcji statycznych. Funkcje statyczne można wywoływać bez tworzenia instancji klasy, co oznacza, że ​​(jeśli nie podasz argumentu nadawcy i nie użyjesz go explicitely), nie będziesz miał obiektu "nadawcy" dla emitowanych sygnałów.

W tych przypadkach, jak sugeruje Lol4t0, wolę także oddzwonienia.

2

w przypadku, gdy ktoś nadal znajduje rozwiązanie, oto co zrobiłem, działa w moim projekcie. 1. dokonać klasa być pojedyncza 2. w statycznej funkcji CB, emitFunction obciążenia od swojej klasy singleton

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

ładne podejście i proste, to jest nawet bezpieczny wątek, ponieważ emituje sygnał. +1 – g24l

Powiązane problemy