QAbstractItemModel and DalegateModel.qml
-
Hello everyone!
I'm developing telegram app for mobile with qt. Got a problem with list of stickers.
Data structure is this:
stickerSet object 1
| sticker 1
| sticker 2
...
| sticker N
stickerSet 2
| sticker 1
| sticker 2
..
| sticker Ncode for sticker model on github here
and qml file is hereProblem: After calling dataChanged for sticker to update its filepath, model doesnt update. (ModelIndex for this item is saved in QMap)
I'm assuming I created wrong qabstractitemmodel, but can't find correct example.
Thanks in advance for any clue. -
@blacky_i said in QAbstractItemModel and DalegateModel.qml:
Problem: After calling dataChanged for sticker to update its filepath, model doesnt update. (ModelIndex for this item is saved in QMap)
- when do you can dataChanged()?
- storing QModelIndexes is always a bad idea
To quickly verify your model implementation you can use ModelTest class (check the console output):
#include <modeltest.h> MyModel *model = new MyModel(this); new ModelTest(model, this);
-
@raven-worx said in QAbstractItemModel and DalegateModel.qml:
when do you can dataChanged()?
After visualising image in qml. If image do not exists on device, data function emits signal to downloadFile from Telegram and stores its QmodelIndex for future update. MEssage from Telegram returns, it updates item in list and calls dataChanged(). But refresing item do not happening.
-
@blacky_i
the problem with storing model indexes is that they are not meant to be stored, since they are only valid until the next model change.
Try changing the QMap to use QPersistentModelIndexes instead (just changing the QMap declaration in the header should be enough) and check if works.Otherwise you will need to show a bit more code.
-
@raven-worx Oh, ok. I added links to github in first post, but I will duplicate as message.
StickerModel.cpp
#include "StickerModel.hpp" #include <QDebug> #include "tdlibQt/TdlibJsonWrapper.hpp" #include "tdlibQt/ParseObject.hpp" namespace tdlibQt { StickerModel::StickerModel(QObject *parent) : QAbstractItemModel(parent), m_client(TdlibJsonWrapper::instance()) { connect(m_client, &TdlibJsonWrapper::stickerSetReceived, this, &StickerModel::addStickerSet); //BUG? Lambda functions requires disconnection before dectruction?. Even disconnection doesnt help connect(m_client, &TdlibJsonWrapper::stickerSetsReceived, this, &StickerModel::stickersSetsReceived); connect(m_client, &TdlibJsonWrapper::stickersReceived, this, &StickerModel::stickersReceived); connect(m_client, &TdlibJsonWrapper::updateFile, this, &StickerModel::updateFile); connect(this, &StickerModel::downloadFileStart, this, &StickerModel::getFile); } StickerModel::~StickerModel() { m_stikerSets.clear(); m_installedStickerSets.clear(); } void StickerModel::getAttachedStickerSets(const int file_id) { m_client->getAttachedStickerSets(file_id); } void StickerModel::getStickerSet(const qint64 set_id) { m_client->getStickerSet(set_id); } void StickerModel::getFavoriteStickers() { m_client->getFavoriteStickers(); } void StickerModel::getRecentStickers() { m_client->getRecentStickers(); } void StickerModel::getInstalledStickers(const bool is_masks) { m_client->getInstalledStickerSets(is_masks); } void StickerModel::addTrendingStickerSets(const QJsonObject &stickerSetsObject) { auto stickerSetsObj = ParseObject::parseStickerSets(stickerSetsObject); for (QSharedPointer<stickerSetInfo> val : stickerSetsObj->sets_) m_trendingStickerSets.append(val); } QSharedPointer<stickerSet> StickerModel::createStickerSet(const QString &name, const QString &title, const std::vector<QSharedPointer<sticker> > &stickers) { if (stickers.size() == 0) return QSharedPointer<stickerSet>(nullptr); QSharedPointer<stickerSet> resultSet = QSharedPointer<stickerSet>(new stickerSet); resultSet->name_ = name.toStdString(); resultSet->title_ = title.toStdString(); resultSet->stickers_ = stickers; return resultSet; } StickerModel::StickerModelState StickerModel::modelState() const { return m_state; } QHash<int, QByteArray> StickerModel::roleNames() const { QHash<int, QByteArray> roles; roles[ID] = "id"; roles[IS_ARCHIVED] = "is_archived"; roles[IS_INSTALLED] = "is_installed"; roles[IS_MASKS] = "is_masks"; roles[IS_OFFICIAL] = "is_official"; roles[IS_VIEWED] = "is_viewed"; roles[TITLE] = "title"; roles[NAME] = "name"; roles[STICKER] = "sticker"; roles[EMOJI] = "emoji"; roles[STICKERS_COUNT] = "stickers_count"; roles[SET_STICKER_THUMBNAIL] = "set_thumbnail"; roles[STICKER_FILE_ID] = "sticker_file_id"; return roles; } QVariant StickerModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() < 0) return QVariant(); int rowIndex = index.row(); int setNumber = index.parent().column() == -1 ? index.parent().row() : rowIndex;//getSetIndex(rowIndex); setNumber = setNumber == -1 ? rowIndex : setNumber; switch (role) { case ID: return QString::number(m_stikerSets[setNumber]->id_); case IS_ARCHIVED: return m_stikerSets[setNumber]->is_archived_; case IS_INSTALLED: return m_stikerSets[setNumber]->is_installed_; case IS_MASKS: return m_stikerSets[setNumber]->is_masks_; case IS_OFFICIAL: return m_stikerSets[setNumber]->is_official_; case IS_VIEWED: return m_stikerSets[setNumber]->is_viewed_; case TITLE: return QString::fromStdString(m_stikerSets[setNumber]->title_); case NAME: return QString::fromStdString(m_stikerSets[setNumber]->name_); case SET_STICKER_THUMBNAIL: return QString::fromStdString(m_stikerSets[setNumber]->stickers_[0]->sticker_->local_->path_); case STICKERS_COUNT: return m_stikerSets[setNumber]->stickers_.size(); case STICKER: if (index.parent().row() == -1) return QVariant(); // m_installedStickerSets[rowIndex]->covers_; if (m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->local_->is_downloading_completed_) return QString::fromStdString(m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->local_->path_); if (m_stikerSets[setNumber]->stickers_[rowIndex]->thumbnail_->photo_->local_->is_downloading_completed_) { emit downloadFileStart(m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->id_, 12, index); return QString::fromStdString(m_stikerSets[setNumber]->stickers_[rowIndex]->thumbnail_->photo_->local_->path_); } emit downloadFileStart(m_stikerSets[setNumber]->stickers_[rowIndex]->thumbnail_->photo_->id_, 12, index); return QVariant(); case EMOJI: { if (index.parent().row() == -1) return QVariant(); QString emojis = ""; emojis += QString::fromStdString(m_stikerSets[setNumber]->stickers_[rowIndex]->emoji_); return emojis; } break; case STICKER_FILE_ID: if (index.parent().row() == -1) return QVariant(); return m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->id_; break; default: return QVariant(); break; } // m_installedStickerSets[rowIndex]->id_; // m_installedStickerSets[rowIndex]->is_archived_; // m_installedStickerSets[rowIndex]->is_installed_; // m_installedStickerSets[rowIndex]->is_masks_; // m_installedStickerSets[rowIndex]->is_official_; // m_installedStickerSets[rowIndex]->is_viewed_; // m_installedStickerSets[rowIndex]->name_; // m_installedStickerSets[rowIndex]->title_; } int StickerModel::rowCount(const QModelIndex &parent) const { if (m_state == SendState || m_state == PreviewState) { if (parent.column() == 0) { return m_stikerSets.at(parent.row())->stickers_.size(); } else return m_stikerSets.size(); } return 0; } void StickerModel::addInstalledStickerSets(const QJsonObject &stickerSetsObject) { auto stickerSetsObj = ParseObject::parseStickerSets(stickerSetsObject); for (QSharedPointer<stickerSetInfo> val : stickerSetsObj->sets_) { m_installedStickerSets.append(val); if (m_state == SendState) getStickerSet(val->id_); } } void StickerModel::addStickerSet(const QJsonObject &stickerSetObject) { auto stickerSetObj = ParseObject::parseStickerSet(stickerSetObject); if (stickerSetObj.data()) { beginInsertRows(QModelIndex(), m_stikerSets.size(), m_stikerSets.size()); m_stikerSets.append(stickerSetObj); endInsertRows(); } } void StickerModel::updateFile(const QJsonObject &fileObject) { if (fileObject["@type"].toString() == "updateFile") processFile(fileObject["file"].toObject()); } void StickerModel::processFile(const QJsonObject &fileObject) { auto file = ParseObject::parseFile(fileObject); if (m_stickerUpdateQueue.keys().contains(file->id_)) { QVector<int> photoRole; QModelIndex viewIndex = m_stickerUpdateQueue[file->id_]; qDebug() << viewIndex << "Row" << viewIndex.row() << "Column" << viewIndex.column() << viewIndex.parent().row(); int rowIndex = viewIndex.row(); int setIndex = viewIndex.parent().row(); if (m_stikerSets[setIndex]->stickers_[rowIndex]->sticker_->id_ == file->id_) m_stikerSets[setIndex]->stickers_[rowIndex]->sticker_ = file; if (m_stikerSets[setIndex]->stickers_[rowIndex]->thumbnail_->photo_->id_ == file->id_) m_stikerSets[setIndex]->stickers_[rowIndex]->thumbnail_->photo_ = file; if (file->local_->is_downloading_completed_) { photoRole.append(STICKER); photoRole.append(SET_STICKER_THUMBNAIL); emit refreshSticker(); } emit dataChanged(index(rowIndex, 0, index(setIndex, -1)), index(rowIndex, 0, index(setIndex, -1)), photoRole); if (file->local_->is_downloading_completed_) m_stickerUpdateQueue.remove(file->id_); } } void StickerModel::stickersReceived(const QJsonObject &setObject) { if (setObject["@extra"].toString() == "getFavoriteStickers") addFavoriteStickers(setObject); else addRecentStickers(setObject); } void StickerModel::stickersSetsReceived(const QJsonObject &setsObject) { if (setsObject["@extra"].toString() == "getTrendingStickerSets") addTrendingStickerSets(setsObject); else addInstalledStickerSets(setsObject); } void StickerModel::changeStickerSet(const QString &setId, const bool isInstalled, const bool isArchived) { m_client->changeStickerSet(setId.toLongLong(), isInstalled, isArchived); } QVariant StickerModel::getStickerUrl(const int setIndex, const int stickerIndex) { return data(index(stickerIndex, 0, createIndex(setIndex, 0)), DataRoles::STICKER); } QVariant StickerModel::getStickerEmoji(const int setIndex, const int stickerIndex) { return data(index(stickerIndex, 0, createIndex(setIndex, 0)), DataRoles::EMOJI); } QVariant StickerModel::getStickersCount(const int setIndex) { return data(index(setIndex, 0), DataRoles::STICKERS_COUNT); } void StickerModel::setSet_id(QString set_id) { if (m_set_id == set_id) return; m_set_id = set_id; emit set_idChanged(m_set_id); } void StickerModel::getFile(const int fileId, const int priority, const QModelIndex indexItem) { m_client->downloadFile(fileId, priority); m_stickerUpdateQueue[fileId] = indexItem; } int StickerModel::columnCount(const QModelIndex &parent) const { return 1; } QModelIndex StickerModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); if (parent.column() > -1) return createIndex(row, column, m_stikerSets.at(parent.row()).data()); return createIndex(row, column); } QModelIndex StickerModel::parent(const QModelIndex &child) const { if (!child.isValid()) return QModelIndex(); stickerSet *childItem = static_cast<stickerSet *>(child.internalPointer()); if (!childItem) return QModelIndex(); if (child.column() == -1) return QModelIndex(); int rowPosition = 0; for (int i = 0; i < m_stikerSets.size(); i++) if (m_stikerSets.at(i).data() == childItem) { rowPosition = i; break; } return createIndex(rowPosition, -1); } bool StickerModel::hasChildren(const QModelIndex &parent) const { return parent.column() == -1; } QString StickerModel::set_id() const { return m_set_id; } void StickerModel::addFavoriteStickers(const QJsonObject &stickersObject) { auto stickersObj = ParseObject::parseStickers(stickersObject); auto resultSet = createStickerSet("Favorite", tr("Favorite"), stickersObj->stickers_); if (resultSet.data()) { beginInsertRows(QModelIndex(), m_stikerSets.size(), m_stikerSets.size()); m_stikerSets.append(resultSet); endInsertRows(); } } void StickerModel::addRecentStickers(const QJsonObject &stickersObjecct) { auto stickersObj = ParseObject::parseStickers(stickersObjecct); auto resultSet = createStickerSet("Recent", tr("Recent"), stickersObj->stickers_); if (resultSet.data()) { beginInsertRows(QModelIndex(), m_stikerSets.size(), m_stikerSets.size()); m_stikerSets.append(resultSet); endInsertRows(); } } void StickerModel::setModelState(StickerModel::StickerModelState state) { if (m_state == state) return; m_state = state; beginResetModel(); m_stikerSets.clear(); m_installedStickerSets.clear(); endResetModel(); switch (m_state) { case SendState: getFavoriteStickers(); getRecentStickers(); getInstalledStickers(); break; case PreviewState: if (set_id().length() > 0) getStickerSet(set_id().toLongLong()); break; case SettingsState: case TrendingState: default: break; } emit modelStateChanged(m_state); } } //tdlibQt
PreviewStickerSetDialog.qml
import QtQuick 2.0 import Sailfish.Silica 1.0 import tdlibQtEnums 1.0 import TelegramModels 1.0 import QtQml.Models 2.3 import org.nemomobile.notifications 1.0 import "../items" Dialog { id:rootPage property alias set_id: stickerModel.set_id property bool _previewEnabled: false property bool _setIsInstalled: false canAccept: !_previewEnabled states:[ State { name: "general" PropertyChanges { target: rootPage _previewEnabled:false } PropertyChanges { target: rootPage backNavigation:true } PropertyChanges { target: previewRect visible:false } }, State { name: "preview" PropertyChanges { target: rootPage _previewEnabled:true } PropertyChanges { target: rootPage backNavigation:false } PropertyChanges { target: previewRect visible:true } StateChangeScript { name: "showNotification" script: notificationPreviewMode.publish() } } ] state: "general" onAccepted: { if(_setIsInstalled) stickerModel.changeStickerSet(set_id,false) else stickerModel.changeStickerSet(set_id,true) } Notification { id:notificationPreviewMode appName: "Depecher" previewBody: qsTr("Sticker preview mode") } StickerModel { id:stickerModel modelState: set_id ==="" ? StickerModel.UknownState : StickerModel.PreviewState } MouseArea { id:previewArea enabled: _previewEnabled focus: _previewEnabled width: parent.width height: parent.height - header.height anchors.bottom: parent.bottom property var component property var previewItem preventStealing: true onPositionChanged: previewThis(mouseX,mouseY) onEnabledChanged: { if(enabled) { component = Qt.createComponent(Qt.resolvedUrl("../items/StickerPreviewComponent.qml")); previewItem = component.createObject(rootPage, {"source": undefined}); previewItem.anchors.centerIn = rootPage previewItem.z = listView.z + 2 } else { if(component) component.destroy() if(previewItem) previewItem.destroy() } } function previewThis(x,y) { //delegateModel do not get item through index //Thats why getting sticker url via model slot var stikerGridIndex = listView.indexAt(x,y+listView.contentY) var grid =listView.itemAt(x,y+listView.contentY).gridSticker if (grid) { var previousHeight = 0; var indexItem = 0 var setIndex = stikerGridIndex //Get height of all gridView previously indexItem = grid.indexAt(x,mapToItem(grid,x,y).y) var stickerUrl = listView.model.model.getStickerUrl(setIndex,indexItem); if(stickerUrl) { previewItem.source = "image://depecherDb/"+stickerUrl; previewItem.emoji = listView.model.model.getStickerEmoji(setIndex,indexItem); } } } onReleased: rootPage.state = "general" } Rectangle { id:previewRect visible: false parent: rootPage z:listView.z + 1 anchors.fill: parent gradient: Gradient { GradientStop { position: 1.0; color: "transparent" } GradientStop { position: 0.0; color: Theme.highlightDimmerColor } } } Column { width:parent.width DialogHeader { id:header acceptText: rootPage._setIsInstalled ? qsTr("Remove %1 stickers").arg(listView.contentItem.children[0].gridSticker.count) :qsTr("Add %1 stickers").arg(listView.contentItem.children[0].gridSticker.count) cancelText: qsTr("Back") } SilicaListView { id:listView width: parent.width height: rootPage.height - header.height clip:true interactive: !_previewEnabled onFlickingChanged: previewTimer.stop() model: DelegateModel { id:stickerSetModel model: stickerModel delegate: Item { width: parent.width height: columnStickers.height property alias itemIndex: stickersGrid property alias gridSticker: stickersGrid property alias stickersCount: stickersGrid.count Column { id:columnStickers width: parent.width height: sectionHeader.height + stickersGrid.height SectionHeader { id:sectionHeader text:title } DelegateModel { id:stickers model: stickerModel rootIndex:listView.model.modelIndex(index) delegate: Image { width: stickersGrid.cellWidth height: width asynchronous: true fillMode: Image.PreserveAspectFit source: "image://depecherDb/" + sticker Connections { target: stickerModel onRefreshSticker:{ stickersGrid.forceLayout() } } MouseArea { anchors.fill: parent enabled: !_previewEnabled onPressed:{ previewTimer.start() } onClicked: { if( rootPage.state === "general") sendUrlItems([{"id":sticker_file_id,"type":TdlibState.Sticker,"url":sticker}]) } onExited: { if(previewTimer.running) previewTimer.stop() } } } } SilicaGridView { id:stickersGrid width: parent.width interactive: !_previewEnabled cellWidth: parent.width/5 cellHeight: cellWidth height:Math.ceil(count / 5) * cellHeight model:stickers } } Component.onCompleted:{ rootPage._setIsInstalled = is_installed } } } } } Timer { id:previewTimer interval: 800 onTriggered: rootPage.state = "preview" } }
-
@blacky_i said in QAbstractItemModel and DalegateModel.qml:
Oh, ok. I added links to github in first post, but I will duplicate as message.
i thought you applied custom changes to the code? I assumed you are using 3rd party code.
-
@raven-worx Many thanks! ModelTest did help. I resloved all Q_ASSERT and model updates fine!) You saved me many nights.
Posting code which works fine:
#include "StickerModel.hpp" #include <QDebug> #include "tdlibQt/TdlibJsonWrapper.hpp" #include "tdlibQt/ParseObject.hpp" namespace tdlibQt { StickerModel::StickerModel(QObject *parent) : QAbstractItemModel(parent), m_client(TdlibJsonWrapper::instance()) { rootSet = QSharedPointer<stickerSet>(new stickerSet); connect(m_client, &TdlibJsonWrapper::stickerSetReceived, this, &StickerModel::addStickerSet); //BUG? Lambda functions requires disconnection before dectruction?. Even disconnection doesnt help connect(m_client, &TdlibJsonWrapper::stickerSetsReceived, this, &StickerModel::stickersSetsReceived); connect(m_client, &TdlibJsonWrapper::stickersReceived, this, &StickerModel::stickersReceived); connect(m_client, &TdlibJsonWrapper::updateFile, this, &StickerModel::updateFile); connect(this, &StickerModel::downloadFileStart, this, &StickerModel::getFile); } StickerModel::~StickerModel() { m_stikerSets.clear(); m_installedStickerSets.clear(); } void StickerModel::getAttachedStickerSets(const int file_id) { m_client->getAttachedStickerSets(file_id); } void StickerModel::getStickerSet(const qint64 set_id) { m_client->getStickerSet(set_id); } void StickerModel::getFavoriteStickers() { m_client->getFavoriteStickers(); } void StickerModel::getRecentStickers() { m_client->getRecentStickers(); } void StickerModel::getInstalledStickers(const bool is_masks) { m_client->getInstalledStickerSets(is_masks); } void StickerModel::addTrendingStickerSets(const QJsonObject &stickerSetsObject) { auto stickerSetsObj = ParseObject::parseStickerSets(stickerSetsObject); for (QSharedPointer<stickerSetInfo> val : stickerSetsObj->sets_) m_trendingStickerSets.append(val); } QSharedPointer<stickerSet> StickerModel::createStickerSet(const QString &name, const QString &title, const std::vector<QSharedPointer<sticker> > &stickers) { if (stickers.size() == 0) return QSharedPointer<stickerSet>(nullptr); QSharedPointer<stickerSet> resultSet = QSharedPointer<stickerSet>(new stickerSet); resultSet->name_ = name.toStdString(); resultSet->title_ = title.toStdString(); resultSet->stickers_ = stickers; return resultSet; } StickerModel::StickerModelState StickerModel::modelState() const { return m_state; } QHash<int, QByteArray> StickerModel::roleNames() const { QHash<int, QByteArray> roles; roles[ID] = "id"; roles[IS_ARCHIVED] = "is_archived"; roles[IS_INSTALLED] = "is_installed"; roles[IS_MASKS] = "is_masks"; roles[IS_OFFICIAL] = "is_official"; roles[IS_VIEWED] = "is_viewed"; roles[TITLE] = "title"; roles[NAME] = "name"; roles[STICKER] = "sticker"; roles[EMOJI] = "emoji"; roles[STICKERS_COUNT] = "stickers_count"; roles[SET_STICKER_THUMBNAIL] = "set_thumbnail"; roles[STICKER_FILE_ID] = "sticker_file_id"; return roles; } QVariant StickerModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() < 0) return QVariant(); stickerSet *childItem = static_cast<stickerSet *>(index.internalPointer()); if (!childItem) return QVariant(); int rowIndex = index.row(); int setNumber = 0;//index.parent().column() == 0 ? index.parent().row() : rowIndex;//getSetIndex(rowIndex); if (childItem == rootSet.data()) { setNumber = index.row(); rowIndex = index.row(); } else { setNumber = index.parent().row(); rowIndex = index.row(); } switch (role) { case ID: return QString::number(m_stikerSets[setNumber]->id_); case IS_ARCHIVED: return m_stikerSets[setNumber]->is_archived_; case IS_INSTALLED: return m_stikerSets[setNumber]->is_installed_; case IS_MASKS: return m_stikerSets[setNumber]->is_masks_; case IS_OFFICIAL: return m_stikerSets[setNumber]->is_official_; case IS_VIEWED: return m_stikerSets[setNumber]->is_viewed_; case TITLE: return QString::fromStdString(m_stikerSets[setNumber]->title_); case NAME: return QString::fromStdString(m_stikerSets[setNumber]->name_); case SET_STICKER_THUMBNAIL: return QString::fromStdString(m_stikerSets[setNumber]->stickers_[0]->sticker_->local_->path_); case STICKERS_COUNT: return m_stikerSets[setNumber]->stickers_.size(); case STICKER: if (index.parent().row() == -1) return QVariant(); // m_installedStickerSets[rowIndex]->covers_; if (m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->local_->is_downloading_completed_) return QString::fromStdString(m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->local_->path_); if (m_stikerSets[setNumber]->stickers_[rowIndex]->thumbnail_->photo_->local_->is_downloading_completed_) { emit downloadFileStart(m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->id_, 12, index); return QString::fromStdString(m_stikerSets[setNumber]->stickers_[rowIndex]->thumbnail_->photo_->local_->path_); } emit downloadFileStart(m_stikerSets[setNumber]->stickers_[rowIndex]->thumbnail_->photo_->id_, 12, index); return QVariant(); case EMOJI: { if (index.parent().row() == -1) return QVariant(); QString emojis = ""; emojis += QString::fromStdString(m_stikerSets[setNumber]->stickers_[rowIndex]->emoji_); return emojis; } break; case STICKER_FILE_ID: if (index.parent().row() == -1) return QVariant(); return m_stikerSets[setNumber]->stickers_[rowIndex]->sticker_->id_; break; default: return QVariant(); break; } // m_installedStickerSets[rowIndex]->id_; // m_installedStickerSets[rowIndex]->is_archived_; // m_installedStickerSets[rowIndex]->is_installed_; // m_installedStickerSets[rowIndex]->is_masks_; // m_installedStickerSets[rowIndex]->is_official_; // m_installedStickerSets[rowIndex]->is_viewed_; // m_installedStickerSets[rowIndex]->name_; // m_installedStickerSets[rowIndex]->title_; } int StickerModel::rowCount(const QModelIndex &parent) const { if (m_state == SendState || m_state == PreviewState) { stickerSet *childItem = static_cast<stickerSet *>(parent.internalPointer()); if (parent == QModelIndex()) return m_stikerSets.size(); if (childItem == rootSet.data()) { return m_stikerSets.at(parent.row())->stickers_.size(); } else return 0; } return 0; } void StickerModel::addInstalledStickerSets(const QJsonObject &stickerSetsObject) { auto stickerSetsObj = ParseObject::parseStickerSets(stickerSetsObject); for (QSharedPointer<stickerSetInfo> val : stickerSetsObj->sets_) { m_installedStickerSets.append(val); if (m_state == SendState) getStickerSet(val->id_); } } void StickerModel::addStickerSet(const QJsonObject &stickerSetObject) { auto stickerSetObj = ParseObject::parseStickerSet(stickerSetObject); if (stickerSetObj.data()) { beginInsertRows(QModelIndex(), m_stikerSets.size(), m_stikerSets.size()); m_stikerSets.append(stickerSetObj); endInsertRows(); } } void StickerModel::updateFile(const QJsonObject &fileObject) { if (fileObject["@type"].toString() == "updateFile") processFile(fileObject["file"].toObject()); } void StickerModel::processFile(const QJsonObject &fileObject) { auto file = ParseObject::parseFile(fileObject); if (m_stickerUpdateQueue.keys().contains(file->id_)) { QVector<int> photoRole; QPersistentModelIndex viewIndex = m_stickerUpdateQueue[file->id_]; qDebug() << viewIndex << "Row" << viewIndex.row() << "Column" << viewIndex.column() << viewIndex.parent().row(); int rowIndex = viewIndex.row(); int setIndex = viewIndex.parent().row(); if (m_stikerSets[setIndex]->stickers_[rowIndex]->sticker_->id_ == file->id_) m_stikerSets[setIndex]->stickers_[rowIndex]->sticker_ = file; if (m_stikerSets[setIndex]->stickers_[rowIndex]->thumbnail_->photo_->id_ == file->id_) m_stikerSets[setIndex]->stickers_[rowIndex]->thumbnail_->photo_ = file; if (file->local_->is_downloading_completed_) { photoRole.append(STICKER); photoRole.append(SET_STICKER_THUMBNAIL); } //For child item emit dataChanged(viewIndex, viewIndex, photoRole); //for thumbnails emit dataChanged(viewIndex.parent(), viewIndex.parent(), photoRole); if (file->local_->is_downloading_completed_) m_stickerUpdateQueue.remove(file->id_); } } void StickerModel::stickersReceived(const QJsonObject &setObject) { if (setObject["@extra"].toString() == "getFavoriteStickers") addFavoriteStickers(setObject); else addRecentStickers(setObject); } void StickerModel::stickersSetsReceived(const QJsonObject &setsObject) { if (setsObject["@extra"].toString() == "getTrendingStickerSets") addTrendingStickerSets(setsObject); else addInstalledStickerSets(setsObject); } void StickerModel::changeStickerSet(const QString &setId, const bool isInstalled, const bool isArchived) { m_client->changeStickerSet(setId.toLongLong(), isInstalled, isArchived); } QVariant StickerModel::getStickerUrl(const int setIndex, const int stickerIndex) { return data(index(stickerIndex, 0, index(setIndex, 0)), DataRoles::STICKER); } QVariant StickerModel::getStickerEmoji(const int setIndex, const int stickerIndex) { return data(index(stickerIndex, 0, index(setIndex, 0)), DataRoles::EMOJI); } QVariant StickerModel::getStickersCount(const int setIndex) { return data(index(setIndex, 0), DataRoles::STICKERS_COUNT); } void StickerModel::setSet_id(QString set_id) { if (m_set_id == set_id) return; m_set_id = set_id; emit set_idChanged(m_set_id); } void StickerModel::getFile(const int fileId, const int priority, const QModelIndex indexItem) { m_client->downloadFile(fileId, priority); m_stickerUpdateQueue[fileId] = indexItem; } int StickerModel::columnCount(const QModelIndex &parent) const { return 1; } QModelIndex StickerModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); if (parent.column() > -1) return createIndex(row, column, m_stikerSets.at(parent.row()).data()); return createIndex(row, column, rootSet.data()); } QModelIndex StickerModel::parent(const QModelIndex &child) const { if (!child.isValid()) return QModelIndex(); stickerSet *childItem = static_cast<stickerSet *>(child.internalPointer()); if (!childItem) return QModelIndex(); if (childItem == rootSet.data()) return QModelIndex(); if (child.column() == -1) return QModelIndex(); int rowPosition = 0; for (int i = 0; i < m_stikerSets.size(); i++) if (m_stikerSets.at(i).data() == childItem) { rowPosition = i; break; } return createIndex(rowPosition, 0, rootSet.data()); } bool StickerModel::hasChildren(const QModelIndex &parent) const { if (rowCount(parent) == 0) return false; return true; } QString StickerModel::set_id() const { return m_set_id; } void StickerModel::addFavoriteStickers(const QJsonObject &stickersObject) { auto stickersObj = ParseObject::parseStickers(stickersObject); auto resultSet = createStickerSet("Favorite", tr("Favorite"), stickersObj->stickers_); if (resultSet.data()) { beginInsertRows(QModelIndex(), m_stikerSets.size(), m_stikerSets.size()); m_stikerSets.append(resultSet); endInsertRows(); } } void StickerModel::addRecentStickers(const QJsonObject &stickersObjecct) { auto stickersObj = ParseObject::parseStickers(stickersObjecct); auto resultSet = createStickerSet("Recent", tr("Recent"), stickersObj->stickers_); if (resultSet.data()) { beginInsertRows(QModelIndex(), m_stikerSets.size(), m_stikerSets.size()); m_stikerSets.append(resultSet); endInsertRows(); } } void StickerModel::setModelState(StickerModel::StickerModelState state) { if (m_state == state) return; m_state = state; beginResetModel(); m_stikerSets.clear(); m_installedStickerSets.clear(); endResetModel(); switch (m_state) { case SendState: getFavoriteStickers(); getRecentStickers(); getInstalledStickers(); break; case PreviewState: if (set_id().length() > 0) getStickerSet(set_id().toLongLong()); break; case SettingsState: case TrendingState: default: break; } emit modelStateChanged(m_state); } } //tdlibQt
Also, to ensure that ModelTest work, I created rootContext as single model and opened qml page with this model to make ModelTest work. Resolving each seg fault resolved issue