2016-06-29 4 views
1

Ich habe eine einfache Signal-Slot-Anwendung mit Qt geschrieben. Ich möchte ein Signal an einen anderen Thread senden, der aus dem Hauptthread ausgeführt wird.So signalisieren Sie einen Steckplatz in einem anderen Thread in Qt

Hier ist mein Code:

class Thread1 : public QThread 
{ 
    Q_OBJECT 


    void run() 
    { 
     exec(); 
    } 
public: 
    Thread1(QObject* parent); 

public slots: 
    void a() 
    { 
     qInfo()<<QThread::currentThreadId(); 
    } 
}; 
class Object : public QObject 
{ 
    Q_OBJECT 
public: 
    Object(){} 
    void start() 
    { 
     qInfo()<<QThread::currentThreadId(); 
     Thread1* thread = new Thread1(this); 
     connect(this,SIGNAL(a()),thread,SLOT(a())); 
     thread->start(); 
     emit a(); 
    } 

signals: 
    void a(); 
}; 

Aber es gibt:

0x7f9851c988c0 
0x7f9851c988c0 

Wie kann ich ein Signal nennen, das ein anderes threadID ausgibt?

Antwort

5

Sie haben es rückwärts. A QThread ist ein Thread-Handle, kein Thread selbst. Wenn Sie etwas in einem anderen Thread ausführen möchten, gehört es in eine Ebene QObject, die Sie zu einem Thread verschieben. Sie müssen nicht von QThread überhaupt ableiten! Sie sollten auch keine QThread Basis QObject auf den Thread selbst verschieben. Was Sie tun, ist ein Griff zum Thread im Thread selbst leben. Sobald der Faden fertig ist, wird der Griff funktionsunfähig (a QObject mit einem Null thread()).

Wenn Sie lediglich Code ausführen müssen, der vollständig ausgeführt wird (z. B. eine Berechnung ausführt), verwenden Sie den Thread-Pool und das QtConcurrent-Framework. Es verwaltet alle Fäden für Sie: Schließlich

#include <QtCore> 
struct Worker : QObject { 
    Q_SLOT void aSlot() { 
    qDebug() << QThread::currentThread(); 
    QThread::currentThread()->quit(); 
    } 
    Q_SIGNAL void aSignal(); 
    Q_OBJECT 
}; 

int main(int argc, char ** argv) { 
    QCoreApplication app{argc, argv}; 
    QThread::currentThread()->setObjectName("main"); 
    QThread thread; 
    thread.setObjectName("thread"); 
    Worker a, b; 
    b.moveToThread(&thread); 
    thread.start(); 
    QObject::connect(&a, &Worker::aSignal, &b, &Worker::aSlot); 
    emit a.aSignal(); // the signal is emitted from the main thread 
    thread.wait(); 
} 

, beachten Sie, dass die QDebug Klasse weiß, wie Ausgabe:

#include <QtConcurrent> 
... 
QThread::currentThread()->setObjectName("main"); 
qDebug() << QThread::currentThread(); 
QtConcurrent::run([]{ qDebug() << QThread::currentThread(); } 

Wenn Sie darauf bestehen, auf die Lebensdauer des Faden Steuerung selbst, würden Sie folgendes tun Adresse, Klasse und Name des Objekts (falls gesetzt), wenn ein Zeiger auf eine QObject übergeben wurde. Also brauchst du nicht QThread::currentThreadId() zu verwenden, die QThread::currentThread() ist ausreichend - und du kannst den Threads mnemonische Namen geben, da sie QObject s sind, immerhin.

+0

Was ist, wenn ich einen 'Worker c;' habe, der in einen dritten Thread verschoben wird und auch mit 'aSignal' verbunden ist. Wenn das Signal ausgesendet wird, wird die Methode aSlot in beiden Arbeitern b und c ausgeführt, jeweils in ihrem eigenen Thread. Recht? – lanoxx

+0

@lanoxx Richtig. –

-2

Implementieren Thread1 Konstruktor wie folgt vor:

Thread1(QObject* parent) { moveToThread(this); } 
+0

Ja, das hat die Arbeit gemacht. aber es muss der Elternteil entfernt werden. –

+0

Warum muss der Elternteil entfernt werden? –

+0

Es wurde ausgedruckt, dass moveToThread nicht für ein Objekt mit übergeordneten Elementen aufgerufen werden kann. –

Verwandte Themen