Qt:信号和槽机制

信号和槽机制

一种回调机制,信号发出后根据连接方式选择什么时候调用回调函数。可以实现跨线程的调用
连接方式

常用自动连接、直接连接、队列连接,阻塞队列链接

Qt::AutoConnection(默认值)

如果接收者位于发出信号的线程中,则使用Qt:::DirectConnection。否则,将使用Qt::QueuedConnection。连接类型是在发出信号时确定的。

Qt::DirectConnection

槽函数运行在发信号的线程里面。信号发出时,槽函数立即被调用,此时 eimt(signal) = slotFunction()。只有当槽函数运行完毕之后eimt(signal) 之后的代码才会被执行

Qt::QueuedConnection

槽函数运行在接收者的线程里, 只有当控制权返回到接收线程的事件循环时,槽函数被调用。

调用此链接时时槽函数调用不是立即进行:
当信号发射和槽函数在同一个线程时,这个线程会先执行完毕当前eimt()之后的代码。执行完毕以后这个线程的事件循环才会继续去调用槽函数。
当信号发色和槽不在同一个线程的时候,槽函数具体调用时机不定,看接收信号的线程

Qt::BlockingQueuedConnection

与Qt:∶QueuedCnnection相同,但发射信号的线程会被阻塞直到槽函数返回。如果接收者所在的线程就是发射信号的线程,会导致死锁。阻塞指的是阻塞该线程的业务代码和事件循环。

信号槽相关宏定义

#define signals public   //将signals定义为public

#define slots  //slots定义是一个空宏,可省

#define Q_OBJECT \  //定义一些元对象,和元调用相关的东西。是信号槽实现的核心机制
public: \
    QT_WARNING_PUSH \
    Q_OBJECT_NO_OVERRIDE_WARNING \
    static const QMetaObject staticMetaObject; \
    virtual const QMetaObject *metaObject() const; \
    virtual void *qt_metacast(const char *); \
    virtual int qt_metacall(QMetaObject::Call, int, void **); \
    QT_TR_FUNCTIONS \
private: \
    Q_OBJECT_NO_ATTRIBUTES_WARNING \
    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
    QT_WARNING_POP \
    struct QPrivateSignal {}; \
    QT_ANNOTATE_CLASS(qt_qobject, "")

#define emit //emit 定义是一个空宏,可省

#define SIGNAL(a)  "2"#a  //"2"加上一个#a, 其中#a就是一个字符串, 例如SIGNAL(valueChanged(int))宏展开后就是"2"valueChanged(int)"

#define SLOT(a) "1"#a	//"1"加上一个#a

信号和槽的连接

Qt信号的一些介绍可以参考下面文档。槽就是一个普通的成员函数,可以是私有也可以是公有
Qt:信号

1、当我们们在cpp文件中使用 emit mySignal() 发送一个信号时,其实就是进行一次信号函数的调用。上面讲过emit宏定义是空的, emit mySignal() 被元对象编译器编译后就会变成 mySignal() ,运行时就相当于运行在相应的moc_xxx.cpp文件中实现的函数体中的内容。

2、在信号函数内,如下图的两个自动生成的信号函数,主要执行的就是Qt元对象QMetaObject的activate函数,该函数将对象指针,元对象引用(staticMetaObject),信号对应的唯一序号标识(按照cpp文件顺序给的), 参数一起传入,并根据信号标识去查找connectList列表,如果有的话就会按照设置的调用方式(Qt::Directconnect等)启动槽函数。

// SIGNAL 0
void SystemService::show_a_message(QString _t1)
{
    void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 0, _a);
}

// SIGNAL 1
void SystemService::show_a_frameless_message(QString _t1, int _t2)
{
    void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };
    QMetaObject::activate(this, &staticMetaObject, 1, _a);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值