2010-06-23 2 views
0

J'essaie de créer un modèle pour stocker des données sur les photos, les icônes et les chemins d'accès.J'ai un problème avec Qt ItemModel personnalisé

class PhotoListItemModel : public QAbstractItemModel { 
    struct ItemModelType { 
     std::string fileName; 
     QImage  image; 
     boost::shared_ptr<char> unique_id; 
    }; 
    std::map<string, ItemModelType> ItemMap; 
    std::map<char*, string>   ItemPointerMap; 
    std::deque<char*>    ItemIndexMap; 

public: 
    PhotoListItemModel(QObject* parent); 
    virtual bool   clear(); 
    virtual int   rowCount (const QModelIndex & parent = QModelIndex()) const; 
    virtual QVariant  data (const QModelIndex & index, int role = Qt::DisplayRole) const; 
    virtual QModelIndex parent (const QModelIndex & index) const; 
    virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const; 
    virtual int   columnCount (const QModelIndex & parent = QModelIndex()) const; 
    //virtual QMap<int, QVariant> itemData (const QModelIndex & index) const 
    virtual bool removeColumns (int column, int count, const QModelIndex & parent = QModelIndex()); 
    virtual bool removeRows (int row, int count, const QModelIndex & parent = QModelIndex()); 

    //index(), parent(), rowCount(), columnCount(), and data() 
    int addFile(const string& str, const QImage& img); 
    bool removeItem(const QModelIndex&); 
}; 

PhotoListItemModel::PhotoListItemModel(QObject* parent) :  QAbstractItemModel(parent) { 

} 
bool PhotoListItemModel::removeItem(const QModelIndex& idx) { 
    return(false); 
} 
bool PhotoListItemModel::removeColumns (int column, int count, const QModelIndex & parent) { 
    return false; 
} 
bool PhotoListItemModel::removeRows (int row, int count, const QModelIndex & parent) { 
    return false; 
} 
int PhotoListItemModel::rowCount (const QModelIndex & parent) const { 
    return 1; 
} 
bool PhotoListItemModel::clear() { 
    return true; 
} 
QVariant  PhotoListItemModel::data (const QModelIndex & index, int role) const { 
    if (!index.isValid()) 
     return QVariant(); 

    if (role == Qt::TextAlignmentRole) { 
     return int(Qt::AlignCenter); 
    } else if (role == Qt::DisplayRole) { 
     char* val = ItemIndexMap[index.column()]; 
     const map<char*, string>::const_iterator iterPtr = ItemPointerMap.find(val); 
     const map<string, ItemModelType>::const_iterator iterImg = ItemMap.find(iterPtr->second); 
     const QImage &img = iterImg->second.image; 

     return img; 
    } 
    return QVariant(); 
} 
QModelIndex PhotoListItemModel::parent (const QModelIndex & index) const { 
    return QModelIndex(); 
} 
QModelIndex PhotoListItemModel::index (int row, int column, const QModelIndex & parent) const { 
    char* ptr = ItemIndexMap[column]; 
    return createIndex(row, column, ptr); 
} 
int PhotoListItemModel::columnCount (const QModelIndex & parent) const { 
    int colCount = ItemMap.size(); 
// if (colCount < 3) 
//  colCount = 3; 

    return colCount; 
} 

int PhotoListItemModel::addFile(const string& str, const QImage& img) { 
    ItemModelType itype; 
     itype.fileName = str; 
     itype.image = img; 
     itype.unique_id = boost::make_shared<char>(); 

    ItemMap[str] = itype; 
    ItemPointerMap[itype.unique_id.get()] = str; 
    ItemIndexMap.push_back(itype.unique_id.get()); 

    int column = ItemIndexMap.size() - 1; 
    QModelIndex mIndex = createIndex(0, column, ItemIndexMap[column]); 
    emit dataChanged(mIndex, mIndex); 

    beginInsertColumns(QModelIndex(), columnCount()-1 , columnCount()-1); 
    bool ret = this->insertColumn(columnCount()-1); 
    endInsertColumns(); 
} 

Le moteur Qt appelle columnCount() plusieurs fois, rowCount un nombre de fois. Mes classes de widget appellent addFile() 6 fois.

PhotoListItemModel :: data() ne s'appelle jamais, donc soit Qt n'écoute pas les changements que je fais, soit il me manque quelque chose. Si je mets columnCount à 6, par exemple, :: data est appelée (et je n'ai pas vérifié que mon QImages est affiché.) Une chose à la fois

Finalement, je longe ceci dans un ListView pour afficher des vignettes de photos .

Répondre

1

tout d'abord, je pense que vous devriez essayer héritant QAbstractTableModel, au lieu de QAbstractItemModel. ce seul changement pourrait résoudre tous vos problèmes. vous pouvez vous débarrasser de vos implémentations parent() et index(), et il prendra soin automatiquement de toutes les base J'ai trouvé que Qt se comporterait comme cela est le QModelIndex Je lui ai donné sa propriété invalide définie sur vrai, ce qui semble être votre cas

+0

fait les changements comme vous le recommandiez: voici les calltree: columnCount(), columnCount(), columnCount(), rowCount(), addFile(), rowCount(), columnCount(), rowCount(), columnCount() x 4. Aucun appel aux données(). –

+0

Suis-je préférable de passer un pointeur sur mon type de données ItemModelType à QStandardItem :: setData? –

+0

Je ne pense pas que setData soit la réponse. Essayez de mettre à jour le code que vous avez posté avec les changements les plus récents et je vais jeter un oeil ici. – Gianni

0

Avez-vous essayé d'appeler insertRows(0, rowCount()); dans le constructeur du modèle? Cela semble toujours bien fonctionner pour moi.

+0

Pourquoi cela fonctionnerait-il? Dans le constructeur, le modèle est toujours vide. –