[关闭]
@Andream 2017-07-15T11:56:54.000000Z 字数 2478 阅读 825

【Qt学习笔记】1.1.1 元对象系统

未分类


目录
1 Qt Core

1.1 基础框架
1.1.1 元对象系统
1.1.2 属性系统
1.1.3 对象模型
1.1.4 对象树
1.1.5 信号/槽

1.2 数据类型和容器

1.3 Qt资源系统

1.4 线程与并发

1.5 其他框架
1.5.1 动画框架
1.5.2 事件系统
1.5.3 状态机系统
1.5.4 JSON
1.5.5 Qt Plugins

2 Qt GUI
3 Qt Widgets
4 Qt SQL
5 Qt Network
6 Qt Test
7 Qt Multimedia

Qt Core是Qt最基础的模块,对Win32API进行了整体的封装,包括:
1. 基础功能
2. 数据类型和容器
3. 事件系统
4. 动画框架
5. 状态机框架
6. JSON

1.1.1 元对象系统

在这个模块,Qt基于C++实现了一些新特性:
1. 信号/槽机制完成对象间的通信
2. 自定义对象
3. 类继承
4. 安全的对象树(对象里面还有对象,即组装)
5. 运行时类型转化

可以概括为:元对象系统

元对象系统(Meta-Object System)

元对象系统为Qt提供了信号/槽机制,运行时类型转换,动态属性等功能。

那么问题来了,它怎么提供这些特性,提供给谁?

它基于:
1. QObject类。该类的子类都支持元对象系统的新特性。
2. Q_OBJECT宏。定义在QObject内部,用于启用元对象系统的特性。
3. Meta-Object Compiler(moc),即元对象编译器。

基本原理:
moc读取.cpp文件,如果该文件定义了Q_OBJECT这个宏,就将这个文件转化为支持meta-object的源文件(#include 一些东西),输出一个.moc文件。

QObject QObject QObject!

QObject内部提供了一系列函数,用于实现新特性:

  1. metaObject() //返回关联的meta-object
  2. connect() disconnect() //绑定/解绑`信号/槽`(Observer mode)
  3. setProperty() dynamicPropertyNames() //动态属性读写
  4. setParent() parent() findChild() findChildren() children() //对象树
  5. event() eventFilter() removeEventFilter() //事件系统
  6. inherits() isWidgetType() isWindowType() //运行时类型识别
  7. startTimer() killTimer() //设置Timer
  8. thread() moveToThread() //线程管理

【信号/槽】

  1. QMetaObject::Connection connect(
  2. const QObject *sender,
  3. const char *signal,
  4. const char *method,
  5. Qt::ConnectionType type = Qt::AutoConnection
  6. ) const
  7. // 当sender的signal函数被调用时,也会调用this->method方法。
  8. // 即把sender的signal和this的method连接在一起
  9. bool disconnect(
  10. const QObject *sender,
  11. const char *signal,
  12. const QObject *receiver,
  13. const char *method
  14. )
  15. // 把sender的signal和receiver的method函数解绑

Example:

  1. QLabel *label = new QLabel;
  2. QLineEdit *lineEdit = new QLineEdit;
  3. QObject::connect(lineEdit, &QLineEdit::textChanged,
  4. label, &QLabel::setText);

【动态属性读写】

  1. bool QObject::setProperty(const char *name, const QVariant &value)
  2. QVariant property(const char *name) const
  3. QList<QByteArray> dynamicPropertyNames() const

【对象树】

【事件系统】

【类型转换】

上面说到,QObject提供了inherits()函数可以实现运行时类型判断,基于这个函数,Qt提供了qobject_cast用于QObject之间的运行时类型转换

qobject_cast和C++的dynamic_cast用法类似:

  1. QObject *obj = new MyWidget;
  2. MyWidget *myWidget = qobject_cast<MyWidget *>(obj);

如果类型转换失败的话,就会返回0。所以我们可以在运行期间根据对象的类型做不同的处理:

  1. if (QLabel *label = qobject_cast<QLabel *>(obj)) {
  2. label->setText(tr("Ping"));
  3. } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
  4. button->setText(tr("Pong!"));
  5. }

【Timer】

  1. int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)
  2. void killTimer(int id)

【线程管理】

  1. QThread * thread() const
  2. void moveToThread(QThread *targetThread)

【继承】

另外,如果我们要定义一个QObject的子类,就一定要定义一个Q_OBJECT的宏,否则我们将无法使用QObject的新特性(因为没有这个宏,moc就不会编译产生子类对应的meta-object)。所以,如果你要继承QObject,不管你是否使用QObject的新特性,最好都声明一下Q_OBJECT这个宏。


在这里,我们只简单了解了一下元对象系统,以及QObject的运行时类型转换和继承时要注意的问题。关于元对象系统的其他部分,将在之后的章节中进一步介绍。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注