0% found this document useful (0 votes)
28 views12 pages

COS3711 Ch12 Reflection - Meta-Objects Presentation Notes

Uploaded by

Justa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views12 pages

COS3711 Ch12 Reflection - Meta-Objects Presentation Notes

Uploaded by

Justa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

COS3711 – Advanced Programming

Virtual Class: COS3711 - 22 - ALL

Chapter 12 – Meta-Objects, Reflection

Lecturer: Dr C Pilkington

Tutor: Ron Barnard


Meta-Objects, Reflection
Outcomes

▪ Understand the MetaObject Pattern (Reflection Pattern)

▪ Understand Qt’s implementation of MetaObject

▪ Implement reflective programming (Fixed / Static and Dynamic)

▪ Understand Qt’s support for run-time type identification

▪ Understand the use of QMetaType


Meta-Objects, Reflection
MetaObject Pattern (Reflection Pattern)
• Reflection – The self-examination of an object's members – provides information
about the properties and methods of an object.
• Meta – 'self-examination', 'self-reflection'.
• Meta object – An object that describes the structure of another object.

• QVariant – Acts like a Union for most Qt data types. A Union is a special C++ class
type that can hold only one of its non-static data members at a time. A QVariant
objects holds a single value of a single type at a time. Types can be multi-valued eg:
QStringList.
• QObject – Base Class of all Qt objects. Useful methods -
◦ metaObject() - returns a pointer to the object's meta-object;
◦ setProperty(name, value) – Set fixed / dynamic properties;
◦ property(QString propertyName) – returns QVariant of property value;
◦ dynamicPropertyNames() - returns a QList of dynamic property names.
Meta-Objects, Reflection
MetaObject Pattern (Reflection Pattern)
• QMetaObject – Useful methods -
◦ className() - returns class name as const char*;
◦ superClass() - returns a pointer to the QMetaObject of the base class;
◦ methodCount() - returns the number of member methods;
◦ propertyCount() - returns the number of member properties – including base class;
◦ property(int index) – returns QMetaProperty – meta-data for property at index.
◦ methodOffset() - index position of class's first method;
◦ propertyOffset() - index position of class's first property – excluding base class;
• QMetaProperty – Provides meta-data about a property. Useful methods -
◦ name() - return property name as const char*;
◦ read() - access property values – returns QVariant;
◦ typeName() - returns type name as const char*.
A class's properties can be discovered at run-time by using QObject, QMetaObject, and
QMetaProperty.
Meta-Objects, Reflection
Fixed Properties (1)
Fixed properties are declared by using the Q_PROPERTY macro in a Class that inherits
QObject -
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])
Meta-Objects, Reflection
Fixed Properties (2)
class Customer : public QObject
{
Q_OBJECT

Q_PROPERTY(QString name READ getName)


Q_PROPERTY(QString id READ getId WRITE setId)
Q_PROPERTY(QString phone READ getPhone WRITE setPhone NOTIFY phoneChanged)

public:
Customer(QString name, QObject *parent = 0);
QString getName() const;
QString getId() const;
void setId(QString id);
QString getPhone() const;
void setPhone(QString phone);

signals:
void phoneChanged(QString newPhone);

private:
QString m_name, m_id, m_phone;

};
Meta-Objects, Reflection
Fixed Properties (3)
Write Fixed properties -
Customer *cust = new Customer("Joe Bloggs");
// Set fixed properties
cust->setId("12345678"); // cust->setProperty(“id”, “12345678”);
cust->setPhone("555-67890");

cust->setObjectName("Harry"); // QObject default property

Read Fixed properties -


// Declare pointer to Object's metaObject
const QMetaObject *metaObj = cust->metaObject();

// Determine how many properties the Object has


int count = metaObj->propertyCount();

// Loop through the properties, extracting name and value


for (int index = 0; index < count; ++index) {

QMetaProperty metaProp = metaObj->property(index);


const char *propName = metaProp.name();
QVariant propValue = cust->property(propName);

out << "Name: " << propName << "\t" << "Value: " + propValue.toString()
<< Qt::endl;
}
Meta-Objects, Reflection
Dynamic Properties (1)
• Fixed properties -
◦ are defined at compile time;
◦ are stored in QMetaObject;
◦ all objects of Class have same meta-object – same properties NOT same values;
• Dynamic properties -
◦ are handled at run-time;
◦ are added to QObject, not QMetaObject;
◦ are specific to each object - objects all have same meta properties, but different
dynamic properties;
◦ Use QObject::setProperty(name, value) to set dynamic properties.
QObject::property(propName) to read properties. (Same as fixed properties).
◦ If name exists, & value is compatible – value is stored, returns True
◦ If value is not compatible, property is not changed, returns False
◦ If name does not exist, new property is added to QObject, returns False.
Meta-Objects, Reflection
Dynamic Properties (2)
Read Dynamic properties -

// Display dynamic properties


out << "\n\n" << "Dynamic Properties" << "\n" << Qt::endl;

// Use dynamicPropertyNames() method of QObject

// Returns QList<QByteArray> of all properties added dynamically

foreach(QByteArray dpName, cust->dynamicPropertyNames()) {

QString name = QString(dpName);

QString value = cust->property(dpName).toString();

out << "Name: " << name << "\t" << "Value: " << value << Qt::endl;
}
Meta-Objects, Reflection
Dynamic Properties (3)
// Check for property type
QString temp;

foreach(QByteArray dpName, cust->dynamicPropertyNames()) {

if ((cust->property(dpName).typeName()) == QString(“QStringList”)) {
temp = cust->property(dpName).toStringList().join(“, ”);
}
else {
temp = cust->property(dpName).toString();
}
}

Alternative approach – use QVariant::canConvert() method to check property type.

setProperty() is case sensitive -


setProperty(“id”, “yourID”) will set / change fixed property.
setProperty(“ID”, “yourID”) will add a new dynamic property.
No WRITE accessor -
setProperty(“name”, “yourName”) will not do anything, no error.
Meta-Objects, Reflection
Example - code
// Another example - Fixed properties

out << "\n\n" << "Class name: " << metaObj->className() << "\n";
out << "Method count: " << metaObj->methodCount() << "\n";
out << "Property count: " << metaObj->propertyCount() << "\n";
out << "Super Class: " << metaObj->superClass()->className() << "\n\n";
out << "Properties: " << "\n" << Qt::flush;

for (int index = metaObj->propertyOffset(); index < metaObj->propertyCount();

++index) {

out << "Name: " << metaObj->property(index).name() << "\n";


out << "Type: " << metaObj->property(index).typeName() << "\n";
out << "Value: " << metaObj->property(index).read(cust).toString()
<< "\n" << Qt::endl;
}
Meta-Objects, Reflection
Example - output

Class name: Customer


Method count: 6
Property count: 4
Super Class: QObject

Properties:
Name: name
Type: QString
Value: Joe Bloggs

Name: id
Type: QString
Value: 987654

Name: phone
Type: QString
Value: 555-67890

You might also like