<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <!-- customtype.qdoc --> <head> <title>Qt 4.6: Custom Type Example</title> <link href="classic.css" rel="stylesheet" type="text/css" /> </head> <body> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td align="left" valign="top" width="32"><a href="http://qt.nokia.com/"><img src="images/qt-logo.png" align="left" border="0" /></a></td> <td width="1"> </td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a> · <a href="classes.html"><font color="#004faf">All Classes</font></a> · <a href="functions.html"><font color="#004faf">All Functions</font></a> · <a href="overviews.html"><font color="#004faf">Overviews</font></a></td></tr></table><h1 class="title">Custom Type Example<br /><span class="subtitle"></span> </h1> <p>Files:</p> <ul> <li><a href="tools-customtype-message-cpp.html">tools/customtype/message.cpp</a></li> <li><a href="tools-customtype-message-h.html">tools/customtype/message.h</a></li> <li><a href="tools-customtype-main-cpp.html">tools/customtype/main.cpp</a></li> <li><a href="tools-customtype-customtype-pro.html">tools/customtype/customtype.pro</a></li> </ul> <p>The Custom Type example shows how to integrate a custom type into Qt's meta-object system.</p> <p>Contents:</p> <ul><li><a href="#overview">Overview</a></li> <li><a href="#the-message-class-definition">The Message Class Definition</a></li> <li><a href="#the-message-class-implementation">The Message Class Implementation</a></li> <li><a href="#using-the-message">Using the Message</a></li> <li><a href="#further-reading">Further Reading</a></li> </ul> <a name="overview"></a> <h2>Overview</h2> <p>Qt provides a range of standard value types that are used to provide rich and meaningful APIs. These types are integrated with the meta-object system, enabling them to be stored in <a href="qvariant.html">QVariant</a> objects, written out in debugging information and sent between components in signal-slot communication.</p> <p>Custom types can also be integrated with the meta-object system as long as they are written to conform to some simple guidelines. In this example, we introduce a simple <tt>Message</tt> class, we describe how we make it work with <a href="qvariant.html">QVariant</a>, and we show how it can be extended to generate a printable representation of itself for use in debugging output.</p> <a name="the-message-class-definition"></a> <h2>The Message Class Definition</h2> <p>The <tt>Message</tt> class is a simple value class that contains two pieces of information (a <a href="qstring.html">QString</a> and a <a href="qstringlist.html">QStringList</a>), each of which can be read using trivial getter functions:</p> <pre> class Message { public: Message(); Message(const Message &other); ~Message(); Message(const QString &body, const QStringList &headers); QString body() const; QStringList headers() const; private: QString m_body; QStringList m_headers; };</pre> <p>The default constructor, copy constructor and destructor are all required, and must be public, if the type is to be integrated into the meta-object system. Other than this, we are free to implement whatever we need to make the type do what we want, so we also include a constructor that lets us set the type's data members.</p> <p>To enable the type to be used with <a href="qvariant.html">QVariant</a>, we declare it using the <a href="qmetatype.html#Q_DECLARE_METATYPE">Q_DECLARE_METATYPE</a>() macro:</p> <pre> Q_DECLARE_METATYPE(Message);</pre> <p>We do not need to write any additional code to accompany this macro.</p> <p>To allow us to see a readable description of each <tt>Message</tt> object when it is sent to the debug output stream, we define a streaming operator:</p> <pre> QDebug operator<<(QDebug dbg, const Message &message);</pre> <p>This facility is useful if you need to insert tracing statements in your code for debugging purposes.</p> <a name="the-message-class-implementation"></a> <h2>The Message Class Implementation</h2> <p>The implementation of the default constructor, copy constructor and destructor are straightforward for the <tt>Message</tt> class:</p> <pre> Message::Message() { } Message::Message(const Message &other) { m_body = other.m_body; m_headers = other.m_headers; } Message::~Message() { }</pre> <p>The streaming operator is implemented in the following way:</p> <pre> QDebug operator<<(QDebug dbg, const Message &message) { QStringList pieces = message.body().split("\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(); }</pre> <p>Here, we want to represent each value depending on how many lines are stored in the message body. We stream text to the <a href="qdebug.html">QDebug</a> object passed to the operator and return the <a href="qdebug.html">QDebug</a> object obtained from its maybeSpace() member function; this is described in more detail in the <a href="custom-types.html#making-the-type-printable">Creating Custom Qt Types</a> document.</p> <p>We include the code for the getter functions for completeness:</p> <pre> QString Message::body() const { return m_body; } QStringList Message::headers() const { return m_headers; }</pre> <p>With the type fully defined, implemented, and integrated with the meta-object system, we can now use it.</p> <a name="using-the-message"></a> <h2>Using the Message</h2> <p>In the example's <tt>main()</tt> function, we show how a <tt>Message</tt> object can be printed to the console by sending it to the debug stream:</p> <pre> Message message(body, headers); qDebug() << "Original:" << message;</pre> <p>You can use the type with <a href="qvariant.html">QVariant</a> in exactly the same way as you would use standard Qt value types. Here's how to store a value using the <a href="qvariant.html#setValue">QVariant::setValue</a>() function:</p> <pre> QVariant stored; stored.setValue(message);</pre> <p>Alternatively, the <a href="qvariant.html#qVariantFromValue">qVariantFromValue</a>() and <a href="qvariant.html#qVariantSetValue">qVariantSetValue</a>() functions can be used if you are using a compiler without support for member template functions.</p> <p>The value can be retrieved using the <a href="qvariant.html#value">QVariant::value</a>() member template function:</p> <pre> Message retrieved = stored.value<Message>(); qDebug() << "Retrieved:" << retrieved; retrieved = qVariantValue<Message>(stored); qDebug() << "Retrieved:" << retrieved;</pre> <p>Alternatively, the <a href="qvariant.html#qVariantValue">qVariantValue</a>() template function can be used if you are using a compiler without support for member template functions.</p> <a name="further-reading"></a> <h2>Further Reading</h2> <p>The custom <tt>Message</tt> type can also be used with direct signal-slot connections; see the <a href="tools-customtypesending.html">Custom Type Sending Example</a> for a demonstration of this. To register a custom type for use with queued signals and slots, such as those used in cross-thread communication, see the <a href="threads-queuedcustomtype.html">Queued Custom Type Example</a>.</p> <p>More information on using custom types with Qt can be found in the <a href="custom-types.html">Creating Custom Qt Types</a> document.</p> <p /><address><hr /><div align="center"> <table width="100%" cellspacing="0" border="0"><tr class="address"> <td width="40%" align="left">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)</td> <td width="20%" align="center"><a href="trademarks.html">Trademarks</a></td> <td width="40%" align="right"><div align="right">Qt 4.6.3</div></td> </tr></table></div></address></body> </html>