I have my own class that inherits from QAbstractItemModel which has tree structure.
I use a couple of views, that display filtered data of this model, using classes derived from QSortFilterProxyModel.
My model structure looks like this:
root
|
-- A
| |-A1
| |-A2
| |-A3
|
-- B
| |-B1
| |-B2
|
... and so on...
Where A, B .... are "main rows" (children of the root), and A1, A2, ... B1, B2... are "children rows" - node rows appended to "main rows".
Now, what I need to do is a QTableView that displays "children rows" only:
A1
A2
A3
B1
B2
But filtering methods I found in QSortFilterProxyModel (filterAcceptsRow, filterAcceptsColumn), operates on main rows only...
How can I do it?
(I found very similar question, but it is still unanswered: QTableView to display only leaves of a tree model implemented with QAbstractItemModel)
I see 3 possible solutions for this problem. First two solutions offered Dmitry Sazonov in his comment for this question:
- Reimplement
QAbstractProxyModel
.
- Reimplement
QAbstractItemModel
and create another model for such view.
The third possible solution is little trick with reimplementation of QStyledItemDelegate
for view. I make small example for such solution. I hope, it will be useful:
#include <QApplication>
#include <QTreeView>
#include <QStyledItemDelegate>
#include <QStandardItemModel>
class ZeroHightItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
ZeroHightItemDelegate(QObject* parent = 0)
: QStyledItemDelegate(parent)
{}
~ZeroHightItemDelegate(){}
public:
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const Q_DECL_OVERRIDE
{
static int defaultHeight = 0;
static bool firstSizeHintFlag = true;
QSize size = QStyledItemDelegate::sizeHint(option, index);
if (firstSizeHintFlag){
defaultHeight = size.height();
firstSizeHintFlag = false;
}
const QAbstractItemModel* model = index.model();
if (!model)
return size;
if (model->hasChildren(index))
size.setHeight(0);
else
size.setHeight(defaultHeight);
return size;
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTreeView myView;
myView.setRootIsDecorated(false);
QStandardItemModel* model = new QStandardItemModel(&myView);
myView.setModel(model);
model->insertColumns(0, 1);
QStandardItem* headerItem = new QStandardItem("Header");
model->setHorizontalHeaderItem(0, headerItem);
QStandardItem* itemA = new QStandardItem("A");
model->appendRow(itemA);
QStandardItem* itemB = new QStandardItem("B");
model->appendRow(itemB);
QStandardItem* itemA1 = new QStandardItem("A1");
QStandardItem* itemA2 = new QStandardItem("A2");
itemA->appendRow(itemA1);
itemA->appendRow(itemA2);
QStandardItem* itemB1 = new QStandardItem("B1");
QStandardItem* itemB2 = new QStandardItem("B2");
QStandardItem* itemB3 = new QStandardItem("B3");
itemB->appendRow(itemB1);
itemB->appendRow(itemB2);
itemB->appendRow(itemB3);
myView.setItemDelegate(new ZeroHightItemDelegate(&myView));
myView.expandAll();
myView.show();
return a.exec();
}
#include "main.moc"