2011-08-26 13 views
5

Utrzymam kod prosty, abyście mogli zobaczyć, co próbuję zrobić;) Jestem świadomy wszystkich problemów z blokowaniem itp. Próbuję dowiedzieć się, jak sygnały i gniazda grają z wątkami.Używanie Qt tam, gdzie wątek roboczy tworzy nowe elementy GUI

W main.cpp:

int main(int argc, char *argv[]) { 
    QApplication app(argc, argv); 
    MyConsole c;  // Subclasses QThread and implements run() 
    MyReceiver r(app); // We pass app to MyReceiver for later (see below) 
    QObject::connect(&c, SIGNAL(sendit()), 
        &r, SLOT(gotit())); 
    c.start();   // Start the worker thread 
    app.exec(); 
} 

Załóżmy, że sygnały i gniazda zostały prawidłowo skonfigurować w plikach nagłówkowych (Przetestowałem i są). Teraz tutaj jest problem:

W MyReceiver.cpp:

void MyReceiver::gotit() 
{ 
    QLabel *label = new QLabel(0, "Hello"); // Some GUI element, any will do 
    app.setMainWidget(*label);    // Some GUI action, any will do 
} 

Pytanie: Ponieważ obiekt MyReceiver powstał w main(), która znajduje się na głównym wątku, to znaczy, że szczeliny (np. gotit()) będzie działał na głównym wątku i dlatego jest bezpieczny do robienia rzeczy GUI? Nawet w przypadkach, gdy sygnał został podniesiony z innego QThread (np. MyConsole w tym przykładzie)?

Czy istnieje lepszy sposób na umożliwienie wątkom pracowniczym interakcji z GUI (na przykład, Obj-C/Cocoa ma podejście typu "Wyślij wiadomość na głównym wątku"). Co to jest "sposób Qt" tego?

Z góry dziękuję!

+0

Czy http://stackoverflow.com/questions/638251/how-to-emit-cross-thread-signal-in-qt odpowiada na pytanie? –

Odpowiedz

1

W „Qt sposób” emitować sygnał z jednego wątku i otrzymać go w innym wątku jest do korzystania z połączenia w kolejce

connect(obj, SIGNAL(foo()), other_obj, SLOT(bar()), Qt::QueuedConnection) 

Z dokumentacji Qt dla Qt :: QueuedConnection:

Szczelina jest wywoływana, gdy sterowanie powraca do pętli zdarzeń wątku odbiorcy. Slot jest wykonywany w wątku odbiorcy.

5

Domyślnie (Qt :: AutoConnection), sloty będą działały w wątku, w którym został utworzony obiekt QObject. Tak więc, niezależnie od tego, z jakiego wątku emitujesz sygnał, slot będzie działał zawsze w wątku, QObject " żyje "w (jeśli pętla zdarzeń Qt działa w tym wątku, w przeciwnym razie wydarzenie nie może zostać dostarczone). Ponieważ główny wątek stanie się wątkiem GUI Qt, będzie działał zgodnie z oczekiwaniami. Jest to rzeczywiście sposób interakcji Qt z GUI. Zobacz też: http://doc.qt.nokia.com/4.7/thread-basics.html (poszukaj powinowactwa wątku).

+0

"bez względu na to, z jakiego wątku wyemitujesz sygnał, slot będzie działał zawsze w tym samym wątku" to zdanie jest nieco ambitne, brzmi to jak gniazdo będzie zawsze uruchamiane w tym samym wątku, z którego sygnał był emitowany. Wiem, że nie masz na myśli tego w ten sposób (ponieważ reszta twojej odpowiedzi jest prawidłowa), ale może mylić innych. –

+1

OK, to było niejednoznaczne, odreagowałem to. Dziękuję za komentarz. – awx

+0

Należy zauważyć, że nadal można wysyłać sygnały nawet bez uruchomionych pętli exec. Wystarczy okresowo wywoływać 'QCoreApplication :: processEvents()' i dla wszystkich zamierzonych celów będzie wyglądało, że masz uruchomione pętle exec. Jest to świetne rozwiązanie w sytuacjach, w których nie można przejąć kontroli nad pętlą systemu operacyjnego, ale nadal potrzebuje wejść/wyjść sygnałów z różnych wątków. – g19fanatic

Powiązane problemy