自定义Qt ItemModel有问题

时间:2010-06-23 13:43:40

标签: c++ qt listview model

我正在尝试创建一个模型来存储有关照片,图标和路径名的数据。

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();
}

Qt引擎多次调用columnCount(),rowCount多次。 我的小部件类调用addFile()6次。

PhotoListItemModel :: data()永远不会被调用,所以要么Qt没有听我正在做的改变,要么我错过了什么。例如,如果我将columnCount设置为6,则会调用:: data(我还没有验证我的QImages显示。有一件事情。

最终我将其绑定到ListView以显示照片缩略图。

2 个答案:

答案 0 :(得分:1)

首先,我认为您应该尝试继承QAbstractTableModel,而不是QAbstractItemModel。仅这一改变可能会解决您的所有问题。然后,您可以摆脱parent()index()实施,并自动处理所有基本内容。我发现Qt的行为就像我传递给它的QModelIndex将其无效属性设置为true,这似乎是你的情况。

答案 1 :(得分:0)

您是否尝试在模型的构造函数中调用insertRows(0, rowCount());?这对我来说似乎总是有效。