Название: QAbstractItemModel: добавление строк [РЕШЕНО]
Отправлено: gureedo от Май 15, 2009, 11:37
Почитал весь раздел про MVC и понял, что это самая подходящая тема для моей проблемы. Есть источник данных, есть модель, есть Q*View. Создаю данные, создаю модель, создаю Q*View и указываю для него свою модель. Пробую добавить с помощью метода void DownloadQueueModel::addFiles(const QString& linkList) - реакции ноль :( Q*View так и не изменяется. Если перед созданием модели в источнике данных уже были какие-то данные, то они нормально отображаются. Что я делаю не так? Сама модель: C++ (Qt) //model.h class DownloadQueueModel : public QAbstractItemModel { Q_OBJECT enum ColumnRoles { NameRole = 0, SizeRole, DownloadedRole, TransferredRole, SourcesRole, SpeedRole, EstimatedTimeRole, MaxRole = EstimatedTimeRole }; public: DownloadQueueModel(QObject *parent = 0); int columnCount( const QModelIndex & parent = QModelIndex() ) const; int rowCount( const QModelIndex & parent = QModelIndex() ) const; QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const; QModelIndex index( int row, int column, const QModelIndex & parent = QModelIndex() ) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex parent( const QModelIndex &child ) const; bool hasChildren( const QModelIndex & parent ) const; bool insertRows( int row, int count, const QModelIndex & parent = QModelIndex() ); void addFiles(const QString& linkList); private: QFileIconProvider *m_iconProvider; QFileIconProvider m_defaultIconProvider; QList<PartFile*> m_fileListToAdd; }; //model.cpp #define EXTRACT_PARTFILE(x) static_cast<PartFile*>((x).internalPointer()) DownloadQueueModel::DownloadQueueModel( QObject *parent ) : QAbstractItemModel(parent) { m_iconProvider = &m_defaultIconProvider; } int DownloadQueueModel::columnCount( const QModelIndex & parent ) const { Q_UNUSED(parent); return MaxRole; } int DownloadQueueModel::rowCount( const QModelIndex &parent ) const { Q_UNUSED(parent); return theApp->downloadQueue->fileCount(); } QVariant DownloadQueueModel::data( const QModelIndex &index, int role ) const { if(!index.isValid()) return QVariant(); PartFile *partFile = NULL; switch(role) { case Qt::DecorationRole: if(index.column() == NameRole) { partFile = EXTRACT_PARTFILE(index); return m_iconProvider->icon(QFileIconProvider::File); } case Qt::DisplayRole: partFile = EXTRACT_PARTFILE(index); switch(index.column()) { case NameRole: return partFile->fileName(); break; case SizeRole: return partFile->size(); break; case DownloadedRole: return partFile->downloaded(); break; case TransferredRole: return partFile->transferred(); break; case SourcesRole: return partFile->sourceCount(); break; case SpeedRole: return 0; break; case EstimatedTimeRole: return 0; break; } } return QVariant(); } QModelIndex DownloadQueueModel::index( int row, int column, const QModelIndex &parent ) const { if(hasIndex(row, column, parent)) return createIndex(row, column, theApp->downloadQueue->m_partFiles.at(row)); return QModelIndex(); } QVariant DownloadQueueModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation != Qt::Horizontal || role != Qt::DisplayRole) return QAbstractItemModel::headerData(section, orientation, role); switch(section) { case NameRole: return tr("Name"); break; case SizeRole: return tr("Size"); case DownloadedRole: return tr("Downloaded"); break; case TransferredRole: return tr("Transferred"); break; case SourcesRole: return tr("Sources"); break; case SpeedRole: return tr("Speed"); break; case EstimatedTimeRole: return tr("ETA"); break; } return QVariant(); } QModelIndex DownloadQueueModel::parent( const QModelIndex& child ) const { Q_UNUSED(child); return QModelIndex(); } bool DownloadQueueModel::hasChildren( const QModelIndex& parent ) const { // root if(EXTRACT_PARTFILE(parent) == NULL) return true; return false; } void DownloadQueueModel::addFiles(const QString& linkList) { m_fileListToAdd = theApp->downloadQueue->prepareToAdd(linkList); if(m_fileListToAdd.count() == 0) return; int row = rowCount(); insertRows(row, m_fileListToAdd.count()); emit dataChanged(index(row,0), index(rowCount()-1, columnCount()-1)); } bool DownloadQueueModel::insertRows( int row, int count, const QModelIndex & parent ) { Q_UNUSED(parent); beginInsertRows(QModelIndex(), row, row + count - 1); theApp->downloadQueue->addFiles(m_fileListToAdd); m_fileListToAdd.clear(); endInsertRows(); return true; }
Название: QAbstractItemModel: добавление строк
Отправлено: Rcus от Май 15, 2009, 12:37
1. Оппа, порт eMule (IS Mod) с богомерзкого MFC? 2. m_fileListToAdd не меняется 3. void QAbstractItemModel::dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight ) [signal]
Название: QAbstractItemModel: добавление строк
Отправлено: gureedo от Май 15, 2009, 13:01
1. Оппа, порт eMule (IS Mod) с богомерзкого MFC? так точно. 2. m_fileListToAdd не меняется 3. void QAbstractItemModel::dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight ) [signal] Исправил в своем предыдущем посте эти вещи, но это ни к чему не привело. все так же 0 реакции. Смешная ошибка с fileListToAdd вышла, но дело не в этом, до этого написано было по другому. к такому варианту пришлось прийти, потому что уже 2 дня не могу найти причину.
Название: QAbstractItemModel: добавление строк
Отправлено: Rcus от Май 15, 2009, 13:11
так точно. Я его тоже как-то хотел портировать, но потом просто попатчил KMLDonkey и забил на это дело :) Насчет проблемы чего-то ничего в голову не приходит, я бы в таком случае поставил бряков и прошелся отладчиком
Название: Re: QAbstractItemModel: добавление строк
Отправлено: gureedo от Май 15, 2009, 20:20
Я его тоже как-то хотел портировать, но потом просто попатчил KMLDonkey и забил на это дело не вариант, ведь я один из разработчиков IS Mod, надо написать полностью адаптированную версию.
Название: Re: QAbstractItemModel: добавление строк
Отправлено: gureedo от Май 18, 2009, 21:44
Проблему решил. Взял QStringList и переделал под себя. Найдите десять отличий между исходником в первом посте и в том, что я сейчас написал. C++ (Qt) //model.h class DownloadQueueModel : public QAbstractItemModel { Q_OBJECT Q_DISABLE_COPY(DownloadQueueModel) enum ColumnRoles { NameRole = 0, SizeRole, DownloadedRole, TransferredRole, SourcesRole, SpeedRole, EstimatedTimeRole, MaxRole = EstimatedTimeRole }; public: explicit DownloadQueueModel(QObject *parent = 0); int columnCount( const QModelIndex &parent = QModelIndex() ) const; int rowCount( const QModelIndex &parent = QModelIndex() ) const; QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; QModelIndex parent( const QModelIndex &child ) const; QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const; bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() ); QVariant headerData(int section, Qt::Orientation orientation, int role) const; bool hasChildren( const QModelIndex &parent = QModelIndex() ) const; void addFiles(const QString &linkList); private: QFileIconProvider *m_iconProvider; QFileIconProvider m_defaultIconProvider; QList<PartFile*> m_fileListToAdd; }; //model.cpp #define EXTRACT_PARTFILE(x) static_cast<PartFile*>((x).internalPointer()) DownloadQueueModel::DownloadQueueModel( QObject *parent ) : QAbstractItemModel(parent) { m_iconProvider = &m_defaultIconProvider; } int DownloadQueueModel::columnCount( const QModelIndex & parent ) const { Q_UNUSED(parent); return MaxRole; } int DownloadQueueModel::rowCount( const QModelIndex &parent ) const { if (parent.isValid()) return 0; return theApp->downloadQueue->fileCount(); } QVariant DownloadQueueModel::data( const QModelIndex &index, int role ) const { if(!index.isValid()) return QVariant(); PartFile *partFile = NULL; switch(role) { case Qt::DecorationRole: if(index.column() == NameRole) { partFile = EXTRACT_PARTFILE(index); return m_iconProvider->icon(QFileIconProvider::File); } case Qt::DisplayRole: partFile = EXTRACT_PARTFILE(index); switch(index.column()) { case NameRole: return partFile->fileName(); break; case SizeRole: return partFile->size(); break; case DownloadedRole: return partFile->downloaded(); break; case TransferredRole: return partFile->transferred(); break; case SourcesRole: return partFile->sourceCount(); break; case SpeedRole: return 0; break; case EstimatedTimeRole: return 0; break; } } return QVariant(); } QModelIndex DownloadQueueModel::index( int row, int column, const QModelIndex &parent ) const { if(hasIndex(row, column, parent)) return createIndex(row, column, theApp->downloadQueue->m_partFiles.at(row)); return QModelIndex(); } QVariant DownloadQueueModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation != Qt::Horizontal || role != Qt::DisplayRole) return QAbstractItemModel::headerData(section, orientation, role); switch(section) { case NameRole: return tr("Name"); break; case SizeRole: return tr("Size"); case DownloadedRole: return tr("Downloaded"); break; case TransferredRole: return tr("Transferred"); break; case SourcesRole: return tr("Sources"); break; case SpeedRole: return tr("Speed"); break; case EstimatedTimeRole: return tr("ETA"); break; } return QVariant(); } QModelIndex DownloadQueueModel::parent( const QModelIndex& child ) const { Q_UNUSED(child); return QModelIndex(); } bool DownloadQueueModel::hasChildren( const QModelIndex& parent ) const { // root if(EXTRACT_PARTFILE(parent) == NULL) return true; return false; } bool DownloadQueueModel::insertRows( int row, int count, const QModelIndex & parent ) { if (count < 1 || row < 0 || row > rowCount(parent)) return false; beginInsertRows(QModelIndex(), row, row + count - 1); theApp->downloadQueue->addFiles(m_fileListToAdd); m_fileListToAdd.clear(); endInsertRows(); return true; } void DownloadQueueModel::addFiles(const QString& linkList) { m_fileListToAdd = theApp->downloadQueue->prepareToAdd(linkList); if(m_fileListToAdd.count() == 0) return; int row = rowCount(); insertRows(row, m_fileListToAdd.count()); }
Название: Re: QAbstractItemModel: добавление строк [РЕШЕНО]
Отправлено: Rcus от Май 18, 2009, 23:03
мда :) diff -up всех найдет Diff int DownloadQueueModel::rowCount( const QModelIndex &parent ) const { - Q_UNUSED(parent); + if (parent.isValid()) + return 0; + return theApp->downloadQueue->fileCount(); }
хм, только мне кажется что если не нужна иерархия то не проще ли было использовать QAbstractTableModel?
|