❝该示例演示将自定义类型集成到Qt的元对象系统中。❞
Qt提供了一系列标准值类型,这些标准值类型用于提供丰富而有意义的API。这些类型与元对象系统集成在一起,使它们可以存储在QVariant对象中,在调试信息(如:qDebug)中写出,并在信号槽通信中传递。
自定义类型也可以与元对象系统集成,只要它们被编写为符合某些简单准则即可。在此示例中,我们介绍一个简单的Message类,描述如何使它与QVariant一起使用,并说明如何扩展它以生成自身的可打印表示形式以用于调试输出。
Message类是一个简单类:
class Message
{
public:
Message() = default;
~Message() = default;
Message(const Message &) = default;
Message &operator=(const Message &) = default;
Message(const QString &body, const QStringList &headers);
QString body() const;
QStringList headers() const;
private:
QString m_body;
QStringList m_headers;
};
如果要将类型集成到元对象系统中,则默认构造函数,复制构造函数和析构函数都是必需的,并且必须是公共的。除此之外,我们还可以自由实现实现类型所需的任何功能,因此我们还包含一个构造函数,可用于设置类型的数据成员。
为了使该类型可以与QVariant一起使用,我们使用Q_DECLARE_METATYPE
宏对其进行声明:
Q_DECLARE_METATYPE(Message);
此外,为了让Message对象可在调试输出流时都能打印,我们定义了一下的流操作符。如果需要出于调试目的而在代码中插入跟踪语句,则此功能很有用。
QDebug operator<<(QDebug dbg, const Message &message)
{
const QString body = message.body();
QVector<QStringRef> pieces = body.splitRef("\r\n", QString::SkipEmptyParts);
if (pieces.isEmpty())
dbg.nospace() << "Message()";
else if (pieces.size() == 1)
dbg.nospace() << "Message(" << pieces.first() << ")";
else
dbg.nospace() << "Message(" << pieces.first() << " ...)";
return dbg.maybeSpace();
}
构建Message类并使用qDebug打印。
Message message(body, headers);
qDebug() << "Original:" << message;
你还可以使用QVariant一起使用,与使用标准Qt值类型完全相同。这是使用QVariant::setValue()
函数存储值的方法:
QVariant stored;
stored.setValue(message);
另外,如果使用的编译器不支持成员模板函数,则可以使用QVariant::fromValue()
函数。使用QVariant::value()
成员模板函数来检索该值:
Message retrieved = stored.value<Message>();
qDebug() << "Retrieved:" << retrieved;
retrieved = qvariant_cast<Message>(stored);
qDebug() << "Retrieved:" << retrieved;
自定义Message类型也可以与直接的信号槽连接一起使用。
C:\Qt\{你的Qt版本}\Examples\{你的Qt版本}\corelib\tools\customtype
https://doc.qt.io/qt-5/qtcore-tools-customtype-example.html