Qt соединяет два сигнала вместе, используя QueuedConnection - PullRequest
24 голосов
/ 21 марта 2012

Qt документация гласит, что возможно соединить два сигнала вместе:

Возможно даже подключить сигнал непосредственно к другому сигналу.

Я пытался:

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

и он работает, как упомянуто, но документация Qt продолжается:

(Это будет издавать второй сигнал немедленно всякий раз, когдапервый излучается.)

Означает ли это, что QueuedConnection не будет работать правильно?Могу ли я соединить два сигнала между потоками?

Причина, по которой я спрашиваю это, заключается в том, что я решил класс сбоев в приложении, избегая этого, но я не уверен, было ли это связано с соединением сигналов вместе.

Ответы [ 2 ]

28 голосов
/ 14 марта 2013

Это не должно сильно отличаться от соединения сигнал / слот.Давайте посмотрим на основной механизм сигналов / слотов.В каждом потоке есть очередь событий, которая поддерживает сигналы (события), которые были отправлены, но еще не обработаны.Поэтому всякий раз, когда выполнение возвращается в цикл обработки событий, очередь обрабатывается.Сам цикл обработки событий не обрабатывает события.Скорее он доставляет их к объектам, чтобы они могли справиться с этим.В этом особом случае я предполагаю, что объект будет излучать другой сигнал, который будет вставлен в очередь.Когда выполнение возвращается в цикл обработки событий, новый сигнал снова обрабатывается объектом.Вот тест, который подтверждает приведенный выше аргумент.

Если вы запустите приложенные коды, то результат будет:

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

, что означает определение типа соединения сигнал-сигнал в виде очереди между потоками.иметь ожидаемое поведение в очереди, которое отклоняет аргумент, который всегда является непосредственным.Если вы определите его как прямой, результат будет:

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

, как и ожидалось.он не генерирует никаких ошибок или предупреждений, и программа также не аварийно завершает работу. Однако этот простой пример не доказывает, что он работает и для большого и сложного.

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";
}
1 голос
/ 16 марта 2013

Взгляните на qt-project, его замечательную вики-страницу о потоках и сигналах.

Потоки, события и объекты QObject :: Сигналы и слоты между потоками

...