qt信号发送间隔短而槽耗时多_Qt信号槽-原理分析

一、问题

学习Qt有一段时间了,信号槽用的也是666,可是对信号槽的机制还是一知半解,总觉着不是那么得劲儿,万一哪天面试被问到了还说不清楚,那岂不是很尴尬。最近抽空研究了下Qt的信号和槽进制,结果发现也不是那么难嘛!不管是同步还是异步,说白了都是函数回调,只是回调的地方变了而已

首先,我们先看如下几个问题,认真的思考下,从以前的知识储备中尝试回答他们,如果说这几个问题你都很清楚,那么恭喜你,你不适合看这篇文章。

moc预编译在干嘛

signals和slots关键字产生的理由

信号槽连接方式有什么区别

信号和槽函数有什么区别

connect到底干了什么

信号触发原理

下面我们就分模块来讲述下Qt的信号槽,首先分析下Moc他到底干了什么,如果没有他信号槽还能行吗?接着我们在来分析下最常用的connect函数,最后在看下信号执行后是怎么触发槽函数的?

二、Moc

qt中的moc 全称是 Meta-Object Compiler,也就是“元对象编译器”,当我们编译C++

文件时,如果类声明中包含了宏Q_OBJECT,则会生成另外一个C++源文件,也就是我们经常看到的moc_xxx.cpp文件,执行流程可能会像这样。

Q_OBJECT是一个非常重要的宏,他是Qt实现元编译系统的一个关键宏,这个宏展开后,里边包含了很多Qt帮助我们写的代码,包括了变量定义、函数声明等等,下边是一个测试例子,是我用moc命令生成的一个moc文件。

分析下面这个几个变量和函数,将有助于我们更好的理解元编译系统

1、变量

- static const qt_meta_stringdata_completerTst_t qt_meta_stringdata_completerTst:存储函数列表

- static const uint qt_meta_data_completerTst:类文件描述

2、Q_OBJECT展开后的函数声明

以下5个函数都是使用Q_OBJECT宏自动生成的

- void xxx::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)

- const QMetaObject xxx::staticMetaObject

- const QMetaObject *xxx::metaObject()

- void *xxx::qt_metacast(const char *_clname)

- int xxx::qt_metacall(QMetaObject::Call _c, int _id, void **_a)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 中,一个信号可以连接多个。如果您想要连接多个,可以使用以下两种方法: 1. 多次连接同一个信号: ```cpp connect(sender, SIGNAL(mySignal()), receiver1, SLOT(mySlot())); connect(sender, SIGNAL(mySignal()), receiver2, SLOT(mySlot())); ``` 这样,当 `sender` 发出 `mySignal()` 信号时,`receiver1` 和 `receiver2` 都会执行 `mySlot()` 函数。 2. 使用 `Qt::DirectConnection` 连接方式,将多个函数链接为单个函数: ```cpp connect(sender, SIGNAL(mySignal()), receiver, SLOT(myCombinedSlot()), Qt::DirectConnection); ``` 在 `receiver` 类中,定义一个 `myCombinedSlot()` 函数,将多个函数的逻辑代码组合在一起。当 `sender` 发出 `mySignal()` 信号时,`receiver` 就会执行 `myCombinedSlot()` 函数,从而执行多个函数的逻辑代码。 在多窗口之间使用信号时,需要注意以下几点: 1. 如果信号函数在不同的窗口中,需要使用 `connect()` 函数将它们连接起来。例如: ```cpp connect(window1, SIGNAL(mySignal()), window2, SLOT(mySlot())); ``` 这样,当 `window1` 中发出 `mySignal()` 信号时,`window2` 中的 `mySlot()` 函数会被执行。 2. 如果信号函数在同一个窗口中,只需要在窗口类的头文件中声明信号函数,并使用 `connect()` 函数将它们连接起来。例如: ```cpp class MyWindow : public QWidget { Q_OBJECT public: explicit MyWindow(QWidget *parent = nullptr); ~MyWindow(); signals: void mySignal(); public slots: void mySlot(); }; // 在构造函数中连接信号函数 MyWindow::MyWindow(QWidget *parent) : QWidget(parent) { connect(this, SIGNAL(mySignal()), this, SLOT(mySlot())); } // 在函数中发出信号 void MyWindow::mySlot() { emit mySignal(); } ``` 这样,在 `MyWindow` 窗口中发出 `mySignal()` 信号时,`mySlot()` 函数就会被执行,从而实现了多窗口之间的信号传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值