how to updating a view's proxy model when the source model changes.
-
CustomListModel.h File
class CustomListModel : public QStandardItemModel { public: CustomListModel(QObject* parent = 0); CustomListModel(const int row, const int coloumn, QObject *parent = 0); Qt::ItemFlags flags(const QModelIndex& index) const; QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); private: QSet<QPersistentModelIndex> checkedItems; };
CustomListModel.cpp File
CustomListModel::CustomListModel(QObject *parent) : QStandardItemModel(parent) { } CustomListModel::CustomListModel(const int row,const int coloumn, QObject *parent) : QStandardItemModel(row,coloumn) { } Qt::ItemFlags CustomListModel::flags(const QModelIndex & index) const { Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index); if (index.isValid()) { return defaultFlags | Qt::ItemIsUserCheckable; } return defaultFlags; } QVariant CustomListModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::CheckStateRole) { return (checkedItems.contains(index) ? Qt::Checked : Qt::Unchecked); } return (QStandardItemModel::data(index, role)); } bool CustomListModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) return false; if ((true)&&(role == Qt::CheckStateRole)) { if (value == Qt::Checked) { checkedItems.insert(index); } else { checkedItems.remove(index); } emit dataChanged(index, index); } else { QStandardItemModel::setData(index, value, role); } return true; } class HardwareProxyModel : public QSortFilterProxyModel { bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); if (!index.isValid()) { return false; } bool supportAc = index.data(Qt::UserRole + 1).toBool(); bool ret = false; if ((!showOnlyAc) || (showOnlyAc && supportAc)) { ret = true; } return ret; } public: void ShowOnlyAcHardware() { showOnlyAc = true; invalidateFilter(); } void ShowAllHardware() { showOnlyAc = false; invalidateFilter(); } private: bool showOnlyAc = false; };
mainUI.cpp file
auto hwList = new QListView; auto hwListProxyModel = new HardwareProxyModel; auto dummy = new CustomListModel(0, 0); hwListProxyModel->setSourceModel(dummy); hwList->setModel(hwListProxyModel); //add item into model for (auto it = newLines.begin(); it != newLines.end(); ++it) { auto count = model->rowCount(); model->insertRow(count); auto index = model->index(count, 0); model->setData(index, it->name, Qt::DisplayRole); model->setData(index, it->channelAmount, Qt::UserRole); model->setData(index, Qt::Unchecked, Qt::CheckStateRole); }
I like to change the value of check box for item. So that, I can change value with help of
hwListProxyModel->setData(hwList->currentIndex(), Qt::Checked, Qt::CheckStateRole);
but I would like to update checkbox with help of sourcemodel.
(source model name = dummy). so that i am trying with help of below line.
hwListProxyModel->sourceModel()->setData(hwList->currentIndex(), Qt::Checked, Qt::CheckStateRole);
but it is not updating view.
Here I found Some Documentation
similar question. http://www.qtcentre.org/threads/55962-Updating-a-view-s-proxy-model-when-the-source-model-changeshttp://doc.qt.io/archives/qt-4.8/qsortfilterproxymodel.html#dynamicSortFilter-prop
How can I update the view if i will change the source model Data? I make many change but something I miss. Please any one give me direction. What change should I make?
-
@Yash001 said in how to updating a view's proxy model when the source model changes.:
hwList->currentIndex()
You're using the wrong model index . See mapToSource/mapFromSource: http://doc.qt.io/qt-5/qsortfilterproxymodel.html#mapToSource
You will also get a warning at runtime about the wrong model index usage. -
Thank you @Christian-Ehrlicher for your answer. I got check mark after getting guidance from you. Thank you so much.
-
@Christian-Ehrlicher is it any way to determine, whether check box check mark is done by User Mouse Click or with help of coding like
sourceModel->setData(hwListProxyModel->mapToSource(hwList->currentIndex()), Qt::Checked, Qt::CheckStateRole);
?I am trying to add another argument or Function before calling setData Function.
I wrote this function for differentiate Click
bool CustomListModel::setDataAndFilterCheckMarkClick(const QModelIndex &index, const QVariant &value, int role, bool ChannelSelected) { if (!index.isValid()) return false; if ((ChannelSelected) && (role == Qt::CheckStateRole)) { if (value == Qt::Checked) { qDebug() << "click get from view "; } else { qDebug() << "click does not get from view"; } } return this->setData(index, value, role); }
checkbox is check whenever I wanted to do using coding. I used code line like
sourceModel->setDataAndFilterCheckMarkClick(hwListProxyModel->mapToSource(hwList->currentIndex()), Qt::Checked, Qt::CheckStateRole,true);
but if the user Click from the view then it won't selected.
I saw in Qcheckbox. which is give me position of the mouse pos.
bool QAbstractButton::hitButton(const QPoint & pos) const
, but i don't know. how can we access the checkbox pointer from the model?In general I would like to differentiate Check box Check from user and Check box check by Coding. what is good way to do this?
-
Your
QStandardItemModel
is useless.QStandardItemModel
can already manageQt::CheckStateRole
In general I would like to differentiate Check box Check from user and Check box check by Coding. what is good way to do this?
While this is usually a sign of something in your design going wrong, you can subclass the delegate and reimplement
editorEvent
. You can start by looking at the source: https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qstyleditemdelegate.cpp.html#_ZN19QStyledItemDelegate11editorEventEP6QEventP18QAbstractItemModelRK20QStyleOptionViewItemRK11QModelIndex -
@VRonin How can i access the checkbox Pointer, So i can identify the pointer of mouse is inside the Checkbox or not?
If I will get access for class QStyledItemDelegatePrivate. then I can get access for the QCheckbox.
const QWidget *widget = QStyledItemDelegatePrivate::widget(option);