QT信号/槽

在我的理解中,QT和Android都是类似的开发框架,都是由开发团队封装了各式各样的接口和数据结构.将一些问题的解决方法简单化
比如QT中将线程封装为QThread,派生类通过重写run方法来将代码投入到新的线程执行,而同样的Android中的线程是Java自带的Thread类,同样是重写run方法来执行线程代码.
由此可见,一些问题的解决方法是存在共性的.

QT的signals slots connect

在程序中引进信号/槽机制,需要元数据 也就是并非任意的类都能添加信号/槽功能

这样会在connect时出错 提示找不到匹配的connect
class sender {
signals:
    void sigSend(int *msg);
};
正确的做法是
class sender : public QThread{
Q_OBJECT
signals:
    void sigSend(int *msg);
};

继承任意元数据的派生类都可以

调用流程通常是:

1
2
3
4
5
 实现信号函数 void sigSend(int *msg);
 在某个方法内调用信号  emit sigSend(&a);
 实现槽函数  void slotRecv(int *msg);
 创建对象后  连接信号与槽 connect(sender, SIGNAL(sigSend(int *)), recver, SLOT(slotRecv(int *)));
 在某个地方调用包含触发信号的方法

元对象系统的构成

  1. QObject为所有需要利用元对象系统的对象提供一个基类。
  2. Q_OBJECT宏,在类的声明体内激活meta-object功能,比如动态属性、信号和槽。
  3. Meta Object Compiler(MOC),为每个QObject派生类生成代码,以支持meta-object功能。
  4. QObject定义了从一个QObject对象访问meta-object功能的接口,Q_OBJECT宏用来告诉编译器该类需要激活meta-object功能,编译器在扫描一个源文件时,如果发现类的声明中有这个宏,就会生成一些代码来为支持meta-object功能——主要是生成该类对应MetaObject类以及对QObject的函数override(重载)。

QObject和QMetaObject

QMetaObject包含了QObject的所谓的元数据,也就是QObject信息的一些描述信息:除了类型信息外,还包含QT中特有的signal&slot信息。

virtual QObject::metaObject();

该方法返回一个QObject对应的metaObject对象,如上文所说,如果一个类的声明中包含了Q_OBJECT宏,编译器会生成代码来实现这个类对应的QMetaObject类,并重载QObject::metaObject()方法来返回这个QMetaObject类的实例引用。这样当通过QObject类型的引用调用metaObejct方法时,返回的是这个引用的所指的真实对象的metaobject。

如果一个类从QObject派生,确没有声明Q_OBJECT宏,那么这个类的metaobject对象不会被生成,这样这个类所声明的signal slot都不能使用,而这个类实例调用metaObject()返回的就是其父类的metaobject对象,这样导致的后果就是你从这个类实例获得的元数据其实都是父类的数据,这显然给你的代码埋下隐患。因此如果一个类从QOBject派生,它都应该声明Q_OBJECT宏,不管这个类有没有定义signal&slot和Property。

这样每个QObject类都有一个对应的QMetaObject类,形成一个平行的类型层次。


The Q_OBJECT macro at the beginning of the class definition is necessary for all classes that define signals or slots 只有加入了Q_OBJECT,你才能使用QT中的signal和slot机制。 比如编写事件接口等程序时,有时会出现如下问题: 在PC端成功编译,但在开发板端却显示错误: QObject::connect: No such slot QWidget::*******() QObject::connect: (sender name: 'unnamed') QObject::connect: (receiver name: 'unnamed') 这时候,就必须在头文件派生类的时候,首先像下面那样引入Q_OBJECT宏: class MyMainWindow : public QWidget { Q_OBJECT ...... } QT中的moc? moc是QT的预编译器,用来处理代码中的slot,signal,emit,Q_OBJECT等。 moc文件是对应的处理代码,也就是Q_OBJECT宏的实现部分,在官方文档上有详细说明,与其文件在同一目录下。
今天项目不能编译过去,最后和没改动的解决方案比较了下发现原来是把Generated MOC Files里面少了两个moc**_xxx.cpp文件!!
原文地址:https://www.cnblogs.com/leijiangtao/p/5475276.html