zoukankan      html  css  js  c++  java
  • Qt::ConnectionType(信号与槽的传递方式)

    Qt::AutoConnection

    自动连接:(默认值)如果信号在接收者所依附的线程内发射,则等同于直接连接。如果发射信号的线程和接受者所依附的线程不同,则等同于队列连接。

    Qt::DirectConnection

    直接连接:当信号发射时,槽函数将直接被调用。无论槽函数所属对象在哪个线程,槽函数都在发射信号的线程内执行。

    Qt::QueuedConnection

    队列连接:当控制权回到接受者所依附线程的事件循环时,槽函数被调用。槽函数在接收者所依附线程执行。也就是说:这种方式既可以在线程内传递消息,也可以跨线程传递消息

    Qt::BlockingQueuedConnection

    与Qt::QueuedConnection类似,但是会阻塞等到关联的slot都被执行。这里出现了阻塞这个词,说明它是专门用来多线程间传递消息的。

    MyObject.h
    #ifndef MYOBJECT_H
    #define MYOBJECT_H
    
    #include 
    
    class MyObject : public QObject
    {
        Q_OBJECT
    
    public:
        explicit MyObject(QObject *parent = 0);
    
    public slots:
        void start();
    };
    
    #endif // MYOBJECT_H
    MyObject.cpp
    #include "MyObject.h"
    #include 
    #include 
    
    MyObject::MyObject(QObject *parent)
        : QObject(parent)
    {
    
    }
    
    void MyObject::start()
    {
        qDebug() << QString("my object thread id:") << QThread::currentThreadId();
    }
    
    main.cpp
    #include "MyObject.h"
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        qDebug() << QString("main thread id:") << QThread::currentThreadId();
    
        MyObject object;
        QThread thread;
        object.moveToThread(&thread);
        QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()));
        thread.start();
    
        return a.exec();
    } 
    查看运行结果:

      "main thread id:" 0xf08

      "my object thread id:" 0x216c

        显然主线程与槽函数的线程是不同的(你可以多次尝试,屡试不爽。。。),因为moveToThread后MyObject所在的线程为QThread,继上面介绍的thread.start()执行后首先会发射started()信号,也就是说started()信号发射是在次线程中进行的,所以无论采取Qt::AutoConnection、Qt::DirectConnection、Qt::QueuedConnection哪种连接方式,主线程与槽函数的线程都是不同的。

    1、修改代码如下:

        MyObject object;
        QThread thread;
        //object.moveToThread(&thread);
        QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::DirectConnection);
        thread.start();
    查看运行结果:

      "main thread id:" 0x2688

      "my object thread id:" 0x2110 

        显然主线程与槽函数的线程是不同的,MyObject所依附的线程为主线程(因为注释掉了moveToThread),继上面介绍的Qt::DirectConnection(无论槽函数所属对象在哪个线程,槽函数都在发射信号的线程内执行)。也就是说started()信号发射是在次线程中进行的,槽函数也是在次线程中进行的,所以主线程与槽函数的线程是不同的。

    2、修改代码如下:

        MyObject object;
        QThread thread;
        //object.moveToThread(&thread);
        QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::QueuedConnection);
        thread.start();

    查看运行结果:

      "main thread id:" 0x24ec

      "my object thread id:" 0x24ec 

        显然主线程与槽函数的线程是相同的,继上面介绍的Qt::QueuedConnection(槽函数在接收者所依附线程执行)。也就是说started()信号发射是在次线程中进行的,但MyObject所依附的线程为主线程(因为注释掉了moveToThread),所以主线程与槽函数的线程必然是相同的。

    3、修改代码如下:

        MyObject object;
        QThread thread;
        //object.moveToThread(&thread);
        QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::AutoConnection);
        thread.start();
    查看运行结果:

      "main thread id:" 0x2700

      "my object thread id:" 0x2700 

        显然主线程与槽函数的线程是相同的,MyObject所依附的线程为主线程(因为注释掉了moveToThread),继上面介绍的Qt::AutoConnection(如果信号在接收者所依附的线程内发射,则等同于直接连接。如果发射信号的线程和接受者所依附的线程不同,则等同于队列连接。)。因为started()信号和MyObject依附的线程不同,所以结果和Qt::QueuedConnection对应的相同,所以主线程与槽函数的线程是相同的。

  • 相关阅读:
    Document
    Document
    Document
    Document
    Document
    Document
    set常见操作:
    select 不存在字段,并设置默认值
    c#为字段设置默认值,以及构造函数初始化List对象。
    ThreadLocal
  • 原文地址:https://www.cnblogs.com/senior-engineer/p/6186226.html
Copyright © 2011-2022 走看看