Qt为C++语言增加的特性在Qt Core模块里实现的。
信号-槽,属性系统,动态类型转换等
元对象系统由以下三个基础组成
- QObject类是所有使用元对象系统的类的基类
- 在一个类的private部分声明Q_OBJECT宏,使得类可使用元对象的特性
- MOC【元对象编译器】为每个QObject的子类提供必要代码来实现元对象系统的特性
MOC工具读取c++源文件,
对有Q_OBJECT宏的类,
为这个类生成另外一个包含有元对象支持代码的C++源文件,这个生成的源文件连同类的实现文件一起被编译和连接。
除信号与槽机制,元对象还提供:
- QObject::metaObject()返回类关联的元对象,元对象类QMetaObject包含了访问元对象的一些接口函数
- QMetaObject::newInstance()函数创建类的一个新的实例
- QObject::inherits(const char* className)函数判断一个对象实例是否是名称为className的类或QObject的子类的实例
- QObject::tr()和QObject::trUtf8()可翻译字符串,用于多语言界面设计
- QObject::setProperty()和QObject::property()用于通过属性名称动态设置和获取属性值
对QObject及其子类,还可使用qobject_cast()函数进行动态投射
例如
设QMyWidget是QWidget的子类
且类定义中声明了Q_OBJECT宏
QObject *obj = new QMyWidget;
// 投射失败时,得到的指针内容为NULL
QMyWidget *myWidget = qobject_cast<QMyWidget*>(obj);
Qt提供一个Q_PROPERTY()可定义属性
基于元对象系统实现
在QObject子类中,用宏Q_PROPERTY()定义属性,格式如下
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL]
)
定义一个返回值类型为type
名为name的属性
用READ,WRITE关键字定义属性的读取,写入函数
还有其他一些关键字定义属性的一些操作特性
属性的类型可为QVariant支持的任何类型,也可为用户自定义类型
Q_PROPERTY宏定义属性的一些主要关键字的意义如下:
- READ指定一个读取属性值的函数,没MEMBER关键字时必须设置READ
- WRITE指定一个设定属性值的函数,只读属性没有WRITE设置
- MEMBER指定一个成员变量与属性关联,称为可读,可写的属性,无需再设置READ和WRITE
- RESET是可选的,用于指定一个设置属性缺省值的函数
- NOTIFY是可选的,用于设置一个信号,属性值变化时发射此信号
- DESIGNABLE表示属性是否在Qt Designer里可见,缺省为true
- CONSTANT表示属性值是一个常数,对一个对象实例,READ指定的函数返回值是常数,但每个实例的返回值可不一样。
- FINAL表示所定义的属性不能被子类重载
QWidget类定义属性的例子
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
不管是否用READ,WRITE定义接口函数
只要知道属性名称,
就可通过QObject::property()读取属性值,通过QObject::setProperty()设置属性值
QPushButton *button = new QPushButton;
QObject *object = button;
object->setProperty("flat", true);
bool isFlat = object->property("flat");
QObject::setProperty()可在运行时为类定义一个新的属性,称为动态属性。
动态属性针对类的实例定义的。
动态属性可用QObject::property()查询
就如在类定义里用Q_PROPERTY宏定义的属性一样
属性系统还有一个宏Q_CLASSINFO()
可为类的元对象定义"名称-值"
class QMyClass : public QObject
{
QOBJECT
Q_CLASSINFO("author", "Wang")
Q_CLASSINFO("company", "UPC")
Q_CLASSINFO("version", "3.0.1")
public:
...
}
用Q_CLASSINGO()宏定义附加类信息后,
可通过元对象的一些函数获取类的附加信息
如classinfo(int)获取某个附加信息
QMetaClassInfo QMetaObject::classInfo(int index) const;
QMetaClassInfo有name和value
对象间通信
QMetaObject::Connection QObject::connect(
const QObject *sender,
const char* signal,
const QObject *receiver,
const char* method,
Qt::ConnectionType type = Qt::AutoConnection
);
// 对应实例
connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int)));
QMetaObject::Connection QObject::connect(
const QObject *sender,
const QMetaMethod &signal,
const QObject *receiver,
const QMetaMethod &method,
Qt::ConnectionType type = Qt::AutoConnection);
// 对应实例
connect(
lineEdit,
&QLineEdit::textChanged,
this,
&widget::on_textChanged);
对于具有不同参数的同名信号不能用指针进行信号-槽的关联
Qt::ConnectionType表明了信号-槽间的关联方式
- Qt::AutoConnection
如信号的接收者与发射者在同一个线程,
就使用Qt::DirecConnection方式
否则,使用Qt::QueuedConnection方式
信号发射时,自动确定关联方式
- Qt::DirectConnection
信号被发射时槽函数立即执行,槽函数与信号在一个线程
- Qt::QueuedConnection
在事件循环回到接收者线程后执行槽函数
槽函数与信号在不同的线程
- Qt::BlockingQueuedConnection
与Qt::QueuedConnectio相似,信号线程会阻塞直到槽函数执行完毕。信号与槽在同一线程这回造成死锁
在槽函数里,用QObject::sender可获取信号发射者的指针
如知道信号发射者的类型,可将指针投射为确定的类型,然后使用这个确定类的接口函数
QSpinBox* spin = qobject_cast<QSpinBox*>(sender());
class A
{
Q_OBJECT
signals:
// 无需实现
void ageChanged(int);
}
void A::fun()
{
emit ageChanged(10);
}
QMetaObject
QMetaProperty
QMetaClassInfo
Qt数据类型 等效定义 字节数
qint8 signed char 1
qint16 signed short 2
qint32 signed int 4
qint64 long long int 8
qlonglong long long int 8
quint8 unsigned char 1
quint16 unsigned short 2
quint32 unsigned int 4
qint64 unsigned long long int 8
qulonglong unsigned long long int 8
uchar unsigned char 1
ushort unsigned short 2
uint unsigned int 4
ulong unsigned long 8
// 可用-qreal float配置为4字节float类型浮点数
qreal double 8
//
qfloat16 2
- QT_VERSION
0xMMNNPP
Qt5.9,1对应于0x050901
- QT_VERSION_CHECK
QT_VERSION_CHECK(m,n,p)返回可与QT_VERSION比较类型
- QT_VERSION_STR
为Qt版本号对应的字符串,如"5.9.0"
- Q_BYTE_ORDER, Q_BIG_ENDIAN, Q_LITTLE_ENDIAN
Q_BYTE_ORDER表示系统内存中数据的字节序
Q_BIG_ENDIAN, Q_LITTLE_ENDIAN分别表示大端和小端
- Q_DECL_IMPORT和Q_DECL_EXPORT
使用或设计共享库时,用于导入或导出库的内容
- Q_DECL_OVERRIDE
类定义中,用于重载一个虚函数
使用Q_DECL_OVERRIDE后,如函数不属于虚函数重载报错
- Q_DECL_FINAL
将一个虚函数定为最终级别,无法在重载
或修饰一个类使其无法被继承
- Q_UNUSED(name)
修饰在函数中定义但未被使用的参数
- foreach(variable, container)
- forever{...}
- qDebug(const char*,...)
- qWarning/qCritica/qFatal/qInfo/...
QStringList
QList
Qt容器类是线程安全的
QList
T不可谓QObject或其任何子类
QList
QLinkedList
QVector
QStack
QQueue
insert/replace/removeAll/move/swap/append/prepend/removeFirst/removeLast
.[index]
.at(index)
isEmpty()/size()
push/pop
enqueue/dequeue
QMap/QMultiMap/QHash/QMultiHash/QSet
Multi指的是一个键关联多个值
contains
QMap map;
map["one"] = 1;
insert/remove
.[key]/.value(key),如果没找到返回一个缺省构造值,使用value时可指定无值时返回值
一个键对应多个值
不提供[]
使用value访问最新插入的键的单个值,values返回所有值,返回值是QList类型
QMap的键必须提供<运算符,
QHash的键必须提供==和名为qHash()的全局散列函数
对每一个容器类,有两个STL类型迭代器
一个用于只读访问,一个用于读写访问
容器类 | 只读迭代器 | 读写迭代器 |
---|---|---|
QList |
QList |
QList |
QLinkedList |
QLinkedList |
QLinkedList |
QVector |
QVector |
QVector |
QSet |
QSet |
QSet |
QMap |
QMap |
QMap |
QMultiMap |
QMap |
QMap |
QHash |
QHash |
QHash |
QMultiHash |
QHash |
QHash |
还可使用const_reverse_iterator/reverse_iterator定义反向迭代器
QList<QString> list;
list << "A" << "B" << "C" << "D";
QList<QString>::const_iterator i;
for(i = list.constBegin(); i!=list.constEnd();++i)
{
qDebug() << *i;
}
QList<QString>::reverse_iterator i;
for(i = list.rbegin();i != list.rend();++i)
{
*i = i->toLower();
}
对QMap和QHash
迭代器的*返回数据项的值
返回键用key()函数,value()返回值
QMap<int, int> map;
...
QMap<int, int>::const_iterator i;
for(i = map.constBegin(); i != map.constEnd(); ++i)
qDebug()->i.key() << ':' << i.value();
foreach(var, container)
{
...
}
对QMap和QHash,foreach访问的是键-值中的值集合
- Qt基本模块,提供了Qt在所有平台上的基本功能
- Qt附加模块,实现一些特定功能的提供附加价值模块
- 增值模块,提供额外价值
- 技术预览模块
- Qt工具
QtCore
Qt GUI
Qt Multimedia
Mt Multimedia Widgets
Qt Network
Qt QML
Qt Quick
Qt Quick Controls
Qt Quick Dialogs
Qt Quick Layouts
Qt SQL
Qt Test
Qt Widgets
Active Qt
Qt 3D
Qt Android Extras
Qt Bluetooth
Qt Concurrent
Qt D-Bus
Qt Gamapad
Qt Image Formats
Qt Mac Extras
Qt NFC
Qt Positioning
Qt Print Support
Qt Purchasing
Qt Sensors
Qt Serial Bus
Qt SVG
Qt WebChannel
Qt WebEngine
Qt WebSockets
Qt Windows Extras
Qt XML
Qt XML Patterns
Qt Charts
Qt Data Visualization
Qt Virtual Keyboard
Qt for Device Creation
Qt Quick Compiler
### Qt工具