Reputation: 1778
I'm using Qt 5.9 on linux. I have a QTreeView where I set a custom model which is derived from QAbstractItemModel and I fill the tree with several plain classes for the tree items. Each treeview item has a checkbox next to it.
I have the following attribute set on the QTreeView ...
treeView->viewport()->setAttribute(Qt::WA_Hover);
so that when the mouse hovers over a tree item, I can capture the event via my delegates paint method.
The problem is that I also have a checkbox in each tree item and I'd like to be able to capture when the state of the checkbox changes, but my delegate doesn't seem to capture that. I can tell what state the checkbox is in when I hover the mouse over the item, but what I want is to be able to immediately know when the state of the checkbox changes w/o having to move the mouse any further.
Any thoughts on how to immediately detect when the state of the checkbox changes in a tree item?
Upvotes: 1
Views: 1216
Reputation: 243907
A possible solution is to track the state change of the checkbox using the editorEvent method:
#include <QtWidgets>
class CheckboxDelegate: public QStyledItemDelegate{
Q_OBJECT
public:
using QStyledItemDelegate::QStyledItemDelegate;
bool editorEvent(QEvent *event,
QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index) override
{
Qt::CheckState last = static_cast<Qt::CheckState>(model->data(index, Qt::CheckStateRole).toInt());
bool res = QStyledItemDelegate::editorEvent(event, model, option, index);
Qt::CheckState current = static_cast<Qt::CheckState>(model->data(index, Qt::CheckStateRole).toInt());
if(last != current)
Q_EMIT stateChanged(index);
return res;
}
Q_SIGNALS:
void stateChanged(const QModelIndex & index);
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStandardItemModel model;
model.setColumnCount(2);
for(int i=0; i<4; ++i){
QList<QStandardItem *> l;
for (int c=0; c< model.columnCount(); ++c) {
QStandardItem *parent = new QStandardItem(QString("%1-%2").arg(i).arg(c));
parent->setCheckable(true);
l << parent;
for (int j=0; j<4; ++j) {
QList<QStandardItem *> ll;
for (int c=0; c< model.columnCount(); ++c) {
QStandardItem *child = new QStandardItem(QString("%1-%2-%3").arg(i).arg(j).arg(c));
child->setCheckable(true);
ll << child;
}
parent->appendRow(ll);
}
}
model.appendRow(l);
}
QTreeView w;
w.viewport()->setAttribute(Qt::WA_Hover);
CheckboxDelegate *delegate = new CheckboxDelegate(&w);
w.setItemDelegate(delegate);
QObject::connect(delegate, &CheckboxDelegate::stateChanged, [](const QModelIndex & index){
QString text = index.data().toString();
Qt::CheckState state = static_cast<Qt::CheckState>(index.data(Qt::CheckStateRole).toInt());
qDebug() << text << state;
});
w.setModel(&model);
w.resize(640, 480);
w.expandAll();
w.show();
return a.exec();
}
Upvotes: 2