Frage

Qt Dokumentation Zustände, die Signale und Slots können direct, queued und auto sein.

Sie hat auch erklärt, dass, wenn das Objekt, das Slot ‚lebt‘ in einem Thread anders als Objekt besitzt, das Signal besitzt, wie wird ein solches Signal emittierende Nachricht Posting - Signal zurückkehrt emittieren sofort und Schlitzverfahren werden in Ziel-Thread des Ereignisschleife aufgerufen werden .

Leider Dokumentation nicht angeben, dass ‚Leben‘ steht und keine Beispiele zur Verfügung. Ich habe den folgenden Code versucht:

main.h:

class CThread1 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        msleep( 200 );
        std::cout << "thread 1 started" << std::endl;
        MySignal();
        exec();
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

main.cpp:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & oThread2, SLOT( MySlot() ) );
    oThread1.start();
    oThread2.start();
    oThread1.wait();
    oThread2.wait();
    return a.exec();
}

Die Ausgabe ist:

thread 2 started
thread 1 started

MySlot() nie aufgerufen :(. Was mache ich falsch?

War es hilfreich?

Lösung

Es gibt durchaus ein paar Probleme mit Ihrem Code:

  • wie gesagt von Evan das emit Schlüsselwort fehlt
  • Alle Objekte im Hauptthread leben, lebt nur der Code in den Laufverfahren in anderen Threads, was bedeutet, dass der MySlot Schlitz im Hauptthread aufgerufen werden würde, und ich bin mir nicht sicher, ob das, was Sie wollen
  • Ihr Steckplatz nie da die Hauptereignisschleife aufgerufen wird nie gestartet worden: Ihre zwei Anrufe () nur warten, nach einer sehr langen Zeit Timeout (und Sie wahrscheinlich Ihre Anwendung töten, bevor das passiert), und ich don ‚t denke, das ist, was Sie wollen entweder sowieso wirklich sie keine Verwendung in Ihrem Code haben.

Dieser Code würde höchstwahrscheinliche Arbeit (obwohl ich habe es nicht getestet) und ich denke, dass es das tut, was Sie es tun wollen:

class MyObject : public QObject
{
    Q_OBJECT
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

class CThread1 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 1 started" << std::endl;
        int i = 0;
        while(1)
        {
           msleep( 200 );
           i++;
           if(i==1000)
              emit MySignal();
        }
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    MyObject myObject;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & myObject, SLOT( MySlot() ) );
    oThread2.start();
    myObject.moveToThread(&oThread2)
    oThread1.start();
    return a.exec();
}

Jetzt wird MyObject in thread2 leben (dank moveToThread).

MySignal sollte von thread1 gesendet wurde (dachte ich auf, dass man nicht sicher bin, könnte es vom Hauptthread gesendet wird, ist es nicht wirklich wichtig ist).

Keine Ereignisschleife wird in thread1 benötigt, da auch ein Signal abgeben eine Ereignisschleife nicht braucht. Eine Ereignisschleife in Thread2 benötigt wird (lanched durch exec ()), um das Signal zu empfangen.

MySlot wird in thread2 aufgerufen werden.

Andere Tipps

Sie Unterklasse nicht QThread für Qt 4.4 +

Während Aiua Antwort gut ist, möchte ich einige Probleme mit QThread und Qt 4.6 oder 4.7 zeigen.

Dieser Artikel fasst zusammen: http: / /blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

Mangelnde Dokumentation auf Qt Teil

Leider ergibt sich das Problem von fehlenden Updates bis hin zur Dokumentation. Vor Qt 4.4 QThread hatte keine Standard-run () Umsetzung, was bedeutete, dass Sie QThread, um eine Unterklasse hatte, es zu benutzen.

Wenn Sie mit Qt 4.6 oder 4.7 dann Sie mit ziemlicher Sicherheit sollte nicht Unterklasse QThread.

Mit moveToThread

Die Keilnuten zum Erhalten in einem Arbeiter-Thread auszuführen sind, um die moveToThread Verfahren zu verwenden, wie Aiua hingewiesen.

Sie sollten das Signal aussenden, um Thread-Funktion wie

zu starten
emit operateCut(examId,examName_examTemplate[examName].studentIdRec,examName_examTemplate[examName].choiceRecA,examName_examTemplate[examName].choiceRecB,examName_examTemplate[examName].objectRecA,examName_examTemplate[examName].objectRecB);

Sie hinzufügen können mehr als ein Argument in diesem Signal

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top