Всем доброго дня.
Я в Qt новичок...Пишу на с++/Qt 5.2.1. Уже неделю не могу разобраться с одной проблемой, может кто подскажет, как решить...
У меня есть исходная_модель-прокси_модель-тривью. В виде дерева отображается вся файловая система, начиная с указанного абс.пути. Дерево строится после нажатия на кнопку "перестроить". В исходной модели реализован один фильтр, с ним все нормально. В прокси-модели еще два, через переопределение
bool filterAcceptsRow() const;
bool FilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
if (filterAcceptsRowItself(sourceRow, sourceParent))
return true;
//accept if any of the children is accepted on it's own merits
if (hasAcceptedChildren(sourceRow, sourceParent)) {
return true;
}
return false;
}
bool FilterProxyModel::filterAcceptsRowItself(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index0 = sourceModel()->index(sourceRow, 3, sourceParent); // получаю индекс по столбцу времени после.модиф.
QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent); // размер файла
QDateTime now = QDateTime::currentDateTime();
QDateTime fileMtime = QDateTime::fromString((sourceModel()->data(index0)).toString(),Qt::LocalDate).addYears(100);
bool timeFilter = mdtime < fileMtime.daysTo(now);
bool sizeFilter = filterFileSize(sourceModel()->data(index1).toString());
return (timeFilter && sizeFilter);
}
bool FilterProxyModel::hasAcceptedChildren(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex item = sourceModel()->index(sourceRow,0,sourceParent);
if (!item.isValid()) {
//qDebug() << "item invalid" << sourceParent << sourceRow;
return false;
}
//check if there are children
int childCount = item.model()->rowCount(item);
if (childCount == 0)
return false;
for (int i = 0; i < childCount; ++i) {
if (filterAcceptsRowItself(i, item))
return true;
//recursive call -> NOTICE that this is depth-first searching, you're probably better off with breadth first search...
if (hasAcceptedChildren(i, item))
return true;
}
return false;
}
Собственно правила фильтрации указаны в filterAcceptsRowItself(). Функция bool filterFileSize() принимает строку с размером, парсит ее и возвращает true, если файл удовлетворяет фильтру. Тут все тоже работает корректно...
Проблема возникает на этапе передачи индекса в представление. Передаю так:
filterModel->setSourceModel(treemodel);
// ...
ui->treeView->setModel(filterModel);
QModelIndex ind = filterModel->mapFromSource(treemodel->setRootPath(path)); // path считывается из виджета lineEdit
if (!ind.isValid()) return;
ui->treeView->setRootIndex(ind);
Если после фильтрации в модели есть данные, то все отлично. Но как только фильтрации не удовлетворяет ни один файл, происходит какая-то неведомая...чудо:
1) либо модель отображается пустой (как и должна, собственно - фильтрация-то вернула false),
2) либо отображается иконка каталога "/" (я так понимаю, это значит, что индекс потерялся или что-то вроде того)
Если первый случай, то после попытки изменить значение фильтра так, чтобы в модель попали данные, программа вылетает. причем не на моих функциях а на цикле exec(), где-то на ассемблерных командах при попытке mov что-то куда-то.
Если второй случай, то после повторного нажатия на кнопку "перестроить дерево", есть шанс, что все-таки отобразятся верные данные.
Может кто подскажет, как мне не терять этот гребаный индекс?
Заранее спасибо.