Custom Type Example▲
Contents:
Overview▲
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 QVariant objects, written out in debugging information and sent between components in signal-slot communication.
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 Message class, we describe how we make it work with QVariant, and we show how it can be extended to generate a printable representation of itself for use in debugging output.
The Message Class Definition▲
The Message class is a simple value class that contains two pieces of information (a QString and a QStringList), each of which can be read using trivial getter functions:
class
Message
{
public
:
Message();
Message(const
Message &
amp;other);
~
Message();
Message(const
QString &
amp;body, const
QStringList &
amp;headers);
QString body() const
;
QStringList headers() const
;
private
:
QString m_body;
QStringList m_headers;
}
;
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.
To enable the type to be used with QVariant, we declare it using the Q_DECLARE_METATYPE() macro:
Q_DECLARE_METATYPE(Message);
We do not need to write any additional code to accompany this macro.
To allow us to see a readable description of each Message object when it is sent to the debug output stream, we define a streaming operator:
QDebug operator
&
lt;&
lt;(QDebug dbg, const
Message &
amp;message);
This facility is useful if you need to insert tracing statements in your code for debugging purposes.
The Message Class Implementation▲
The implementation of the default constructor, copy constructor and destructor are straightforward for the Message class:
Message::
Message()
{
}
Message::
Message(const
Message &
amp;other)
{
m_body =
other.m_body;
m_headers =
other.m_headers;
}
Message::
~
Message()
{
}
The streaming operator is implemented in the following way:
QDebug operator
&
lt;&
lt;(QDebug dbg, const
Message &
amp;message)
{
const
QString body =
message.body();
QVector&
lt;QStringRef&
gt; pieces =
body.splitRef("
\r\n
"
, QString::
SkipEmptyParts);
if
(pieces.isEmpty())
dbg.nospace() &
lt;&
lt; "Message()"
;
else
if
(pieces.size() ==
1
)
dbg.nospace() &
lt;&
lt; "Message("
&
lt;&
lt; pieces.first() &
lt;&
lt; ")"
;
else
dbg.nospace() &
lt;&
lt; "Message("
&
lt;&