Qt 使用 QueuedConnection 将两个信号连接在一起

标签 qt thread-safety signals slot

Qt documentation声明可以将两个信号连接在一起:

It is even possible to connect a signal directly to another signal.



我试过:
connect(x, SIGNAL(S()), y, SIGNAL(func()));

它的工作原理如上所述,但 Qt 文档仍在继续:

(This will emit the second signal immediately whenever the first is emitted.)



这是否意味着 QueuedConnection 将无法正常工作?我可以跨线程连接两个信号吗?

我问这个的原因是因为我通过避免这种情况解决了应用程序上的一类崩溃,但我不确定这是否与将信号连接在一起有关。

最佳答案

它与信号/插槽连接应该没有太大区别。让我们来看看信号/槽的底层机制。每个线程中都有一个事件队列,用于维护已发出但尚未处理的信号(事件)。所以每当执行返回到事件循环时,队列就会被处理。事件循环本身不处理事件。相反,它将它们传递给对象,以便它们可以处理它。在这种特殊情况下,我认为该对象会发出另一个信号,该信号将插入队列中。当执行返回到事件循环时,对象再次处理新信号。这是一个证明上述论点的测试。

如果您运行附加的代码,输出将是:

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

这意味着将信号-信号连接类型定义为在线程之间排队具有预期的排队行为,即拒绝它始终是立即的参数。如果将其定义为直接,则输出将为:
before signal()
slot() called 
after signal()

正如预期的那样。它不会产生任何错误或警告,程序也不会崩溃。然而,这个简单的例子并不能证明它也适用于大型复杂的例子。

主.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();
}

测试连接.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

测试连接.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";
}

关于Qt 使用 QueuedConnection 将两个信号连接在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9798195/

相关文章:

c++ - 在Qt中获取qrc文件的路径

c++ - QT:如何正确清理QSettings以防止内存泄漏?

c++ - 将双端队列传递给新的 pthread

python - 如果忽略 SIGCHLD,Firefox Webdriver 将无法工作

database - 将 MIT-BIH 心律失常心电图数据库加载到 MATLAB

python - CTRL+C 不会中断在 Python 中使用 CTYPES 对共享库的调用

qt - 我正在尝试以 gif 格式保存 QImage

c++ - QWidgets可以添加到QWindow吗?

c - OpenMP,并行写入不同的数组元素

c - 这个函数是完全线程安全的吗?