web-dev-qa-db-fra.com

Qt connecter deux signaux ensemble en utilisant QueuedConnection

Qt documentation indique qu'il est possible de connecter deux signaux ensemble:

Il est même possible de connecter un signal directement à un autre signal. 

J'ai essayé:

connect(x, SIGNAL(S()), y, SIGNAL(func()));

et cela fonctionne comme mentionné, mais la documentation Qt continue:

(Ceci émettra le deuxième signal immédiatement chaque fois que le premier est émis.)

Est-ce que cela signifie que QueuedConnection ne fonctionnera pas correctement? Puis-je connecter deux signaux sur des threads?

La raison pour laquelle je pose cette question est parce que j’ai résolu ce problème, mais je ne sais pas si cela était lié à la connexion de signaux.

24
dashesy

Cela ne devrait pas être très différent d’une connexion signal/slot. Jetons un coup d'œil au mécanisme sous-jacent des signaux/slots. Il existe une file d’événements dans chaque thread qui conserve les signaux (événements) qui ont été émis mais pas encore traités. Ainsi, chaque fois que l'exécution revient à la boucle d'événements, la file d'attente est traitée. La boucle d'événement elle-même ne gère pas les événements. Au contraire, il les livre aux objets afin qu'ils puissent le gérer. Dans ce cas particulier, je suppose que l'objet émettrait un autre signal qui serait inséré dans la file d'attente. Lorsque l'exécution retourne à la boucle d'événement, le nouveau signal est à nouveau traité par l'objet. Voici un test qui prouve l'argument ci-dessus.

Si vous exécutez les codes attachés, le résultat serait:

before signal() 
after signal() 
slot() called

ce qui signifie que définir un type de connexion signal-signal comme étant en file d'attente entre les threads a le comportement attendu en file d'attente, ce qui rejette l'argument qu'il est toujours immédiat. Si vous le définissez comme direct, le résultat serait:

before signal()
slot() called 
after signal()

comme prévu. il ne génère aucune erreur ni aucun avertissement, et le programme ne se bloque pas aussi bien. Cependant, cet exemple simple ne prouve pas que cela fonctionne aussi pour un grand et complexe.

main.cpp:

#include <QtGui/QApplication>
#include "dialog.h"
#include "testssconnection.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    TestSignalSignalConnection * t = new TestSignalSignalConnection();
    t->start();

    return a.exec();
}

testssconnection.h:

#ifndef TESTSSCONNECTION_H
#define TESTSSCONNECTION_H

#include <QObject>
#include <QThread>

class TestSignalSignalConnection : public QThread
{
    Q_OBJECT
public:
    explicit TestSignalSignalConnection(QObject *parent = 0);

    void run();

signals:
    void signal1();
    void signal2();

public slots:
    void slot();
};

#endif // TESTSSCONNECTION_H

testssconnection.cpp:

#include "testssconnection.h"
#include <QtCore>

TestSignalSignalConnection::TestSignalSignalConnection(QObject *parent) :
    QThread(parent)
{
}

void TestSignalSignalConnection::run()
{
    TestSignalSignalConnection *t = new TestSignalSignalConnection();

    this->connect(this,SIGNAL(signal1()),t,SIGNAL(signal2()), Qt::QueuedConnection);
    t->connect(t,SIGNAL(signal2()), t,SLOT(slot()), Qt::DirectConnection);

    qDebug() << "before signal()";
    emit signal1();
    qDebug() << "after signal()";

    exec();
}

void TestSignalSignalConnection::slot()
{
    qDebug() << "slot() called";
}
27
Ameer Jewdaki

Jetez un coup d'œil à qt-project, c'est une page wiki géniale sur les threads et les signaux.

Threads, Events and QObjects :: Signaux et emplacements sur les threads

1
kikeenrique