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

原创 2016年03月03日 23:34:17

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是不安全的。同样的原因,调用存在于另一个线程中的对象的函数是不安全的。



版权声明:本文为博主原创文章,可以转载但必须注明出处。 https://blog.csdn.net/nirendao/article/details/50792564

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

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

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

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

Qt的Signal和Slot机制(一)

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

QT signal & slot 定义及用法 .

来源: http://blog.csdn.net/kaffeel/article/details/5568954   信号和槽是Qt编程的一个重要部分。这个机制可以在对象之间彼此并不了解的情况...
  • u010779194
  • u010779194
  • 2013-09-03 15:49:12
  • 813

Qt5 中的 signal/slot 新语法

Qt 5 Alpha 已经发布。我们会在后面的文章中看到 Qt 5 的新变化。今天,我们先来看一下 Qt 5 带来的一个最主要的变化:signal/slot 机制的改变。 Qt 5 之前的语法 ...
  • hemmingway
  • hemmingway
  • 2015-12-25 13:38:47
  • 2337

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

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

Qt的signal和slot使用心得

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

QT信号(SIGNAL)与槽(SLOT)

QT中的信号槽是QT框架中十分重要,同时也是十分特别的机制之一。对于它的理解,你可以把它当做Windows系统中的消息处理函数。比如,当一个按钮控件被单击了一下,那么它就会发出一个信号(signal)...
  • YZS_L_H
  • YZS_L_H
  • 2016-06-04 15:14:41
  • 1412

QT signals and slots

从百度空间看到的文章,我关注的地方是: 1、signals前面不可加public、private和protected进行修饰;slots前面可以加,因为Qt说槽函数可以当普通函数使用。 2、sig...
  • MichealTX
  • MichealTX
  • 2011-10-10 13:16:47
  • 14938

PyQt5学习笔记06----Qt Designer自定义信号emit及传参

from PyQt5 import QtWidgets,QtCore from untitled import Ui_Form import time class MyWindow(QtWid...
  • a359680405
  • a359680405
  • 2015-04-20 15:06:24
  • 17396
收藏助手
不良信息举报
您举报文章:QT的signal和slot的几种常见使用场景
举报原因:
原因补充:

(最多只允许输入30个字)