I've been experimenting with the model/view programming methodology and hope soon to fully understand it's implementation in Qt. Suppose that you have a class, say Customer, and that class has Q_PROPERTYs (like firstName, lastName, etc..). Now you want to hold an Address Book, so you make a model.
First Question: do you subclass QAbstractListModel, or QAbstractTableModel?
I chose to subclass the table model, and hold the records in rows (QList<Customer*> m_list), and the properties of each Customer in the columns. In the interests of future extendability, I'd like for the model's implementation of columnCount() to return the number of properties available for the class Customer. So this exercise was to see if I colud write a model that would automatically account for any changes made to class Customer. That is; if I change class Customer by addition or removal of properties, I don't want to have to change the model.
int myModel::columnCount() {
// we have to subtract the properties gained through inheritance
// from the total count
static int ret = Customer::staticMetaObject()->propertyCount()
- Customer::staticMetaObject->propertyOffset();
return ret;
}
int myModel::rowCount() {
return m_list()->size();
}
int myModel::columnCount() {
// we have to subtract the properties gained through inheritance
// from the total count
static int ret = Customer::staticMetaObject()->propertyCount()
- Customer::staticMetaObject->propertyOffset();
return ret;
}
int myModel::rowCount() {
return m_list()->size();
}
To copy to clipboard, switch view to plain text mode
Now in order to retrieve our data, we have to reimplement the data function. But this is where I ran into a bit of trouble.
if ( index.isValid() )
if ( index.row() < 0 || rowCount() <= index.row() )
if ( index.column < 0 || columnCount() <= index.column() )
if ( role == Qt::DisplayRole ) {
int col = index.column() + Customer::staticMetaObject()->propertyOffset();
Customer *c = m_list.at( index.row() );
char *name = ??? // somehow we have to map col into a property name
return c->property( name );
}
}
QVariant BrushModel::data( const QModelIndex &index, int role ) const {
if ( index.isValid() )
return QVariant();
if ( index.row() < 0 || rowCount() <= index.row() )
return QVariant();
if ( index.column < 0 || columnCount() <= index.column() )
return QVariant();
if ( role == Qt::DisplayRole ) {
int col = index.column() + Customer::staticMetaObject()->propertyOffset();
Customer *c = m_list.at( index.row() );
char *name = ??? // somehow we have to map col into a property name
return c->property( name );
}
return QVariant();
}
To copy to clipboard, switch view to plain text mode
Perhaps this is just a flawed design and there are better ways to go about this. I may have overlooked something in the documentation surrounding metaobects but I could not find a way to map from an index to a property name. I did find an indexOfProperty(char *name) function, but nothing which goes the other direction.
Bookmarks