@Andream
2017-07-15T11:56:54.000000Z
字数 2478
阅读 825
未分类
目录
1 Qt Core1.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 Plugins2 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
在这个模块,Qt基于C++实现了一些新特性:
1. 信号/槽
机制完成对象间的通信
2. 自定义对象
3. 类继承
4. 安全的对象树(对象里面还有对象,即组装)
5. 运行时类型转化
可以概括为:元对象系统
元对象系统为Qt提供了信号/槽
机制,运行时类型转换,动态属性等功能。
那么问题来了,它怎么提供这些特性,提供给谁?
它基于:
1. QObject
类。该类的子类都支持元对象系统的新特性。
2. Q_OBJECT
宏。定义在QObject内部,用于启用元对象系统的特性。
3. Meta-Object Compiler(moc),即元对象编译器。
基本原理:
moc读取.cpp文件,如果该文件定义了Q_OBJECT
这个宏,就将这个文件转化为支持meta-object的源文件(#include 一些东西),输出一个.moc文件。
QObject内部提供了一系列函数,用于实现新特性:
metaObject() //返回关联的meta-object
connect() disconnect() //绑定/解绑`信号/槽`(Observer mode)
setProperty() dynamicPropertyNames() //动态属性读写
setParent() parent() findChild() findChildren() children() //对象树
event() eventFilter() removeEventFilter() //事件系统
inherits() isWidgetType() isWindowType() //运行时类型识别
startTimer() killTimer() //设置Timer
thread() moveToThread() //线程管理
QMetaObject::Connection connect(
const QObject *sender,
const char *signal,
const char *method,
Qt::ConnectionType type = Qt::AutoConnection
) const
// 当sender的signal函数被调用时,也会调用this->method方法。
// 即把sender的signal和this的method连接在一起
bool disconnect(
const QObject *sender,
const char *signal,
const QObject *receiver,
const char *method
)
// 把sender的signal和receiver的method函数解绑
Example:
QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit, &QLineEdit::textChanged,
label, &QLabel::setText);
bool QObject::setProperty(const char *name, const QVariant &value)
QVariant property(const char *name) const
QList<QByteArray> dynamicPropertyNames() const
上面说到,QObject提供了inherits()函数可以实现运行时类型判断
,基于这个函数,Qt提供了qobject_cast
用于QObject之间的运行时类型转换
。
qobject_cast
和C++的dynamic_cast
用法类似:
QObject *obj = new MyWidget;
MyWidget *myWidget = qobject_cast<MyWidget *>(obj);
如果类型转换失败的话,就会返回0。所以我们可以在运行期间根据对象的类型做不同的处理:
if (QLabel *label = qobject_cast<QLabel *>(obj)) {
label->setText(tr("Ping"));
} else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
button->setText(tr("Pong!"));
}
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)
void killTimer(int id)
QThread * thread() const
void moveToThread(QThread *targetThread)
另外,如果我们要定义一个QObject的子类,就一定要定义一个Q_OBJECT的宏,否则我们将无法使用QObject的新特性(因为没有这个宏,moc就不会编译产生子类对应的meta-object)。所以,如果你要继承QObject,不管你是否使用QObject的新特性,最好都声明一下Q_OBJECT这个宏。
在这里,我们只简单了解了一下元对象系统,以及QObject的运行时类型转换和继承时要注意的问题。关于元对象系统的其他部分,将在之后的章节中进一步介绍。