关闭

QT的signal和slot的几种常见使用场景

标签: QT
3305人阅读 评论(1) 收藏 举报
分类:

signal和slot是QT的经典应用。本文就signal和slot的几种常用场景做一简单介绍。


首先,先看2个类A和B的定义。

a.h如下:

#ifndef A_H
#define A_H

#include <QObject>

class A : public QObject
{
    Q_OBJECT
public:
    void emitSignalA() {
        signalA();
    }

signals:
    void signalA();
};

#endif // A_H

b.h如下:

#ifndef B_H
#define B_H

#include <QDebug>
#include <QObject>

class B : public QObject
{
    Q_OBJECT
public slots:
    void slotB() {
        qDebug()<<"slotB() is called.";
    }
};

#endif // B_H

三个常用场景都使用这2个类,但main.cpp不同。

场景一、A和B都在主线程中,且signal也在主线程中emit,那么B在主线程中执行slot,所以这是同步的。

1.cpp如下:

#include <QCoreApplication>
#include "a.h"
#include "b.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    A a;
    B b;
    QObject::connect(&a,SIGNAL(signalA()),&b,SLOT(slotB()));

    a.emitSignalA();

    return app.exec();
}


场景二、A生在子线程中,B生在主线程中,A在子线程中emit signal,而B在主线程中执行slot,所以这是异步的。

#include <QCoreApplication>
#include <QThread>
#include "a.h"
#include "b.h"

B * g_pB = NULL;

class T : public QThread
{
public:
    void run() {
        A a;
        connect(&a,SIGNAL(signalA()),g_pB,SLOT(slotB()));
        a.emitSignalA();
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    B b;
    g_pB = &b;
    T t;
    t.start();

    return app.exec();
}

场景三、A、B都出生在主线程中,而A在子线程中emit signal,B在主线程中执行slot,所以这还是异步的。

#include <QCoreApplication>
#include <QThread>
#include "a.h"
#include "b.h"

A * g_pA = NULL;
B * g_pB = NULL;

class T : public QThread
{
public:
    void run() {
        connect(g_pA,SIGNAL(signalA()),g_pB,SLOT(slotB()));
        g_pA->emitSignalA();
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    B b;
    g_pB = &b;
    A a;
    g_pA = &a;
    T t;
    t.start();

    return app.exec();
}

由上可见,对场景三,虽然A和B都是在主线程初始,但因为A在子线程emit signal,所以B仍会在主线程执行slot,仍然是异步的。


当然,以上这些都是因为connect()的最后一个参数连接类型的默认值是AutoConnection。其详细解释可见:http://doc.qt.io/qt-5/threads-qobject.html ,本人译文在:http://blog.csdn.net/nirendao/article/details/50642701 . 摘要如下:

Qt支持如下的signal-slot连接类型:

  • Auto Connection(默认) :如果发射signal和接收的对象在同一个线程,那么行为等同于Direct Connection;否则,行为等同于Queued Connection. 
  • Direct Connection:当signal被发射后,slot立即被调用。slot在signal发射者所在的线程中被执行,而未必需要在接收者的线程中。
  • Queued Connection:当控制回到接收者的event loop后,slot才被调用。slot被执行在接收者的线程中。
  • Blocking Queued Connection:slot的调用情形和Queued Connection相同,不同的是当前的线程会阻塞住,直到slot执行结束返回。注意,在同一个线程中使用这种类型进行连接会导致死锁。
  • Unique Connection:行为与Auto Connection相同,但是连接只会在“不会与已存在的连接相同”时建立,即:如果相同的signal已经被连接到相同的slot,那么连接就不会被再次建立,而connect()函数会返回false. 

通过传递一个参数给connect()函数来指定连接类型。要知道的是,如果event loop运行在接收者的线程中,而sender和receiver在不同的线程时,使用Direct Connection是不安全的。同样的原因,调用存在于另一个线程中的对象的函数是不安全的。



1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Qt的Signal和Slot机制(一)

最近在用Qt开发项目,它的Signal和Slot机制引起了我的兴趣,闲暇无聊,看了下源代码,写下了一些自己的心得。但其中难免有错误之处,望各位看官不吝指出。第一节 Signal和Slot的钥匙我们知道...
  • SuperFPE
  • SuperFPE
  • 2010-08-02 14:38
  • 10185

QT窗体间传值总结之Signal&Slot

在写程序时,难免会碰到多窗体之间进行传值的问题。依照自己的理解,我把多窗体传值的可以使用的方法归纳如下:       1.使用QT中的Signal&Slot机制进行传值;       2.使用全局...
  • hanxing0
  • hanxing0
  • 2013-06-13 16:18
  • 19994

Qt的signal和slot使用心得

1、connect指定的SIGNAL和SLOT的成员函数,不能携带参数名,只能带参数类型,比如:QObject::connect(pushButton, SIGNAL(clicked(bool)), ...
  • ztz0223
  • ztz0223
  • 2013-05-29 19:05
  • 13641

QT核心:signal-slot 信号/槽机制 最详细最通俗易懂的一篇

原创翻译:信号&槽(QT 基础) crystalblue,sand.fj.wen翻译 cxt_programmer校正 2010-10-22 14:55| 发布者: Vincent| 查看: 1...
  • zkl99999
  • zkl99999
  • 2016-12-21 16:51
  • 2615

信号(Signal)与槽(Slot)-Qt中的典型机制

因为下一篇关于Boost的文章会涉及到事件处理的问题,里面用的是信号和槽的机制,先拿Qt里的这个机制预研一下。诶,Boost这是够厉害的,什么先进就包含什么!要知道我以前一直以为这是Qt的专利呢。当然...
  • JuanA1
  • JuanA1
  • 2011-07-25 22:09
  • 14206

信号(Signal)与槽(Slot)-Qt中的典型机制

因为下一篇关于Boost的文章会涉及到事件处理的问题,里面用的是信号和槽的机制,先拿Qt里的这个机制预研一下。诶,Boost这是够厉害的,什么先进就包含什么!要知道我以前一直以为这是Qt的专利呢。当然...
  • wjeson
  • wjeson
  • 2012-07-02 16:41
  • 4069

Qt中信号与槽机制中emit的应用

信号与槽机制是qt的核心,一个信号可以接多个槽,多个信号也可以接一个槽,当然一个信号也可以接一个槽。本文的重点是讲述emit的应用,emit是qt中定义的宏,是用来发送一个信号,然后你再写一个槽函数。...
  • qq_29630271
  • qq_29630271
  • 2016-09-23 20:27
  • 11992

Qt的信号和槽是如何工作的

用Qt做过开发的朋友,不知道是否曾为下面这些问题疑惑过: 我们知道Qt是基于C++的,Qt写的代码最终还是要由C++编译器来编译,但是我们的Qt代码中有很多C++里没有的关键字,比如slots\sig...
  • NewThinker_wei
  • NewThinker_wei
  • 2014-04-02 12:24
  • 29205

Qt跨线程发送信号与元数据

Qt的signals/slots是可以用在线程间的。由于事件循环(event loop)是在主线程完成的,所以在非主线程发送一个信号时,对应的槽函数将会由主线程执行。 熟悉多线程的读者应该都感受到...
  • luotuo44
  • luotuo44
  • 2014-09-19 10:46
  • 5315

关于linux异步通知signal 和QT的信号槽

项目要进行ARM和DSP之间的通信,查了很多资料,最终决定用HPI,HPI驱动写完后,要写QT应用程序,方案是qt端给信号中断DSP,然后DSP处理完一帧数据后,中断ARM。 ARM接收到中断后调用r...
  • zhang2531
  • zhang2531
  • 2016-03-05 22:04
  • 952
    个人资料
    • 访问:174924次
    • 积分:2960
    • 等级:
    • 排名:第13897名
    • 原创:101篇
    • 转载:36篇
    • 译文:28篇
    • 评论:25条
    最新评论