3 Qt类库概述
3.1 Qt核心特点
3.1.1 概述
(1)组成
- QObject类:所有使用MOS的类的基类
- Q_OEJECT宏:使类对象可以使用元对象的特性(添加宏才能被MOC预处理),如动态属性、信号-槽
- MOC:Meta-Object Compiler,将具有Qt特性的程序转换为标准C++兼容的形式,再由标准C++进行编译
(2)元对象的一些功能
- QObkect::metaObject():返回类关联的元对象
- QObject::newInstance():创建类的一个新的实例
- QObject::inherits(const char *className):判断一个对象是否是名为className的类或QObject类子类的对象
- QObject::tr()和QObject::trUtf8():翻译字符串
- QObject::setProperty()和QObject::property():设置/访问属性
- qobject_cast()进行动态投射(dynamic cast),eg:
//QMyWidget是QWidget的子类,并且在类定义中声明了Q_OBJECT宏
QObject *obj = new QMyWidget;
QWidget *widget = qobject_cast<QWidget*>(obj);//则widget指针指向一个QWidget对象
QMyWidget *myWidget = qobject_cast<QMyWidget*>(obj);//则myWidget指针指向一个QMyWidget对象
QLabel *label = qobject_cast<QLabel*>(obj);//则label是一个NULL指针,因为QMyWidget类不是QLabel的子类
3.1.3 属性系统
(1)定义
Q_PROPERTY()宏定义属性,基于MOS实现,属性系统与C++编译器无关。
Q_PROPERTY宏定义一个返回值类型为type、名称为name的属性,用READ、WRITE关键字定义属性的读取、写入函数,其格式:
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]
[REQUIRED])
tip:以下来自Qt官网
- A READ accessor function is required if no MEMBER variable was specified. It is for reading the property value. Ideally, a const function is used for this purpose, and it must return either the property’s type or a const reference to that type. e.g., QWidget::focus is a read-only property with READ function, QWidget::hasFocus().
- A WRITE accessor function is optional. It is for setting the property value. It must return void and must take exactly one argument, either of the property’s type or a pointer or reference to that type. e.g., QWidget::enabled has the WRITE function QWidget::setEnabled(). Read-only properties do not need WRITE functions. e.g., QWidget::focus has no WRITE function.
- A MEMBER variable association is required if no READ accessor function is specified. This makes the given member variable readable and writable without the need of creating READ and WRITE accessor functions. It’s still possible to use READ or WRITE accessor functions in addition to MEMBER variable association (but not both), if you need to control the variable access.
- A RESET function is optional. It is for setting the property back to its context specific default value. e.g., QWidget::cursor has the typical READ and WRITE functions, QWidget::cursor() and QWidget::setCursor(), and it also has a RESET function, QWidget::unsetCursor(), since no call to QWidget::setCursor() can mean reset to the context specific cursor. The RESET function must return void and take no parameters.
- A NOTIFY signal is optional. If defined, it should specify one existing signal in that class that is emitted whenever the value of the property changes. NOTIFY signals for MEMBER variables must take zero or one parameter, which must be of the same type as the property. The parameter will take the new value of the property. The NOTIFY signal should only be emitted when the property has really been changed, to avoid bindings being unnecessarily re-evaluated in QML, for example. Qt emits automatically that signal when needed for MEMBER properties that do not have an explicit setter.
- A REVISION number is optional. If included, it defines the property and its notifier signal to be used in a particular revision of the API (usually for exposure to QML). If not included, it defaults to 0.
+The DESIGNABLE attribute indicates whether the property should be visible in the property editor of GUI design tool (e.g., Qt Designer). Most properties are DESIGNABLE (default true). Instead of true or false, you can specify a boolean member function.
- The SCRIPTABLE attribute indicates whether this property should be accessible by a scripting engine (default true). Instead of true or false, you can specify a boolean member function.
- The STORED attribute indicates whether the property should be thought of as existing on its own or as depending on other values. It also indicates whether the property value must be saved when storing the object’s state. Most properties are STORED (default true), but e.g., QWidget::minimumWidth() has STORED false, because its value is just taken from the width component of property QWidget::minimumSize(), which is a QSize.
- The USER attribute indicates whether the property is designated as the user-facing or user-editable property for the class. Normally, there is only one USER property per class (default false). e.g., QAbstractButton::checked is the user editable property for (checkable) buttons. Note that QItemDelegate gets and sets a widget’s USER property.
- The presence of the CONSTANT attribute indicates that the property value is constant. For a given object instance, the READ method of a constant property must return the same value every time it is called. This constant value may be different for different instances of the object. A constant property cannot have a WRITE method or a NOTIFY signal.
- The presence of the FINAL attribute indicates that the property will not be overridden by a derived class. This can be used for performance optimizations in some cases, but is not enforced by moc. Care must be taken never to override a FINAL property.
- The presence of the REQUIRED attribute indicates that the property should be set by a user of the class. This is not enforced by moc, and is mostly useful for classes exposed to QML. In QML, classes with REQUIRED properties cannot be instantiated unless all REQUIRED properties have been set.
实质上来讲,应该就是为Qt类设置新的属性,以及读取、写入属性值等时触发的操作。
(2)使用
通过QObject::property()和QObject::setProperty()分别读取和设置属性值,其中:
bool QObject::setProperty(const char *name, const QVariant &value)
Sets the value of the object’s name property to value.
If the property is defined in the class using Q_PROPERTY then true is returned on success and false otherwise. If the property is not defined using Q_PROPERTY, and therefore not listed in the meta-object, it is added as a dynamic property and false is returned.
Information about all available properties is provided through the metaObject() and dynamicPropertyNames().
Dynamic properties can be queried again using property() and can be removed by setting the property value to an invalid QVariant. Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent to be sent to the object.
Note: Dynamic properties starting with “q” are reserved for internal purposes.
即可以设置类的动态属性。
(3)Q_CLASSINFO()宏
为类的元对象附加“名称-值”信息,如
Q_CLASSINFO("author","shchyan")
使用
QMetaClassInfo QMetaObject::classInfo(int index) const
获取指定index的附加信息对象,再使用name()和value()函数获得其附加信息的名称和值。
3.1.4 信号和槽
基于MOS,理论上说比回调函数稍慢(需要查找连接的对象和槽函数),但更灵活。
其声明
QMetaObject::Connection
connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
QMetaObject::Connection
connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)
QMetaObject::Connection
connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection)
QMetaObject::Connection
connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QMetaObject::Connection
connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)
自定义信号
eg:
class QPerson:public QObject
{
Q_OBJECT
private:
int m_age=10;
pubilc:
void incAge();
signals:
void ageChanged(int value);//信号函数不能有返回值,无需实现,使用emit发射信号
}
void QPerson::incAge()
{
m_age++;
emit ageChanged(m_age);
}
3.2 Qt全局定义(<QtGlobal>文件中)
3.2.1 数据类型定义
3.2.2 函数
多为函数模板,基础数学运算在<QtMath>中定义
3.2.3 宏定义
3.3 容器类
3.3.1 概述
3.3.2 顺序容器类(Sequence container)
(1)QList<T>
数组列表,eg:
QList<QString> list;
list<<"one"<<"two"<<"three";
QString str1 = list[1];//"two"
QString str1 = list.at(0);//"one"
(2)QLinkedList<T>
链式列表
(3)QVector<T>
动态数组,以下标索引访问数据
(4)QStack<T>
栈,进栈:push(),出栈:pop()
(5)QQueue<T>
队列,进队:enqueue(),出队:dequeue()
3.3.3 关联容器类(associative container)
(1)QSet<T>
集合,查找速度更快
(2)QMap<Key, T>
字典,Key指关键字类型,T指值类型
(3)QMultiMap<Key, T>
是QMap的子类,多值字典,一个关键字对应多个值,不能使用下标[]访问值,使用value()返回QList对象
(4)QHash<Key, T>
基于散列表实现字典功能的模板类,其与QMap的区别:
QHash比QMap的查找速度更快(QHash基于哈希函数,QMap基于AVL)
(5)QMultiHash<Key, T>
多值映射的QHash
3.4 容器类的迭代
迭代器(iterator)为访问容器类里的数据提供了统一的方法,Qt有有Java迭代器和STL迭代器两种类型,前者更易于使用并且提供了一些高级功能,后者效率更高。
容器类 |
迭代器类型 |
只读迭代器 |
读写迭代器 |
QList<T> |
Java迭代器 |
QListIterator<T> |
QMutableIterator<T> |
QList<T> |
STL迭代器 |
QList<T>::const_iterator |
QList<T>::iterator |
foreach关键字(<QtGlobal>定义的一个宏)
foreach(variable, container)
eg:
QLinkedList<QString> list;
foreach(const QString &str,list){
if (str,isEmpty())
break;
qDebug<<str;
}
3.5 Qt类库的模块
- Qt Essentials
- Qt Core
- Qt GUI
- Qt Multimedia
- Qt Multimedia Widgets
- Qt Network
- Qt QML
- Qt Quick
- Qt Quick Controls
- Qt Dialogs
- Qt Quick Layouts
- Qt SQL
- Qt Test
- Qt Widgets
- Qt Add-Ons
- Value-Add Modules
- Technology Preview Modules
- Qt Tools