LINUX.ORG.RU

QAbstractProxyModel + subtree

 


0

2

Всем привет,

Не могу догнать как сделать прокси-модель, которая отображала бы поддерево исходной модели.

Итак, к примеру - есть QAbstractItemModel:

A
-B
--C
--D
-E
--F
--G

Хочется в определённую вьюху отображать часть исходной модели, к примеру при выборе B:

B
-C
-D

Как вариант, пробую реализовать метод mapToSource прокси-модели следующим образом:

QModelIndex TRDeviceFilterModel::mapToSource(const QModelIndex &proxyIndex) const
{
	if (proxyIndex == QModelIndex())
		return m_root;

	return QSortFilterProxyModel::mapToSource(proxyIndex);
}

Но что делать с mapFromSource? Как его реализовать? И вообще, правильно ли задачу выделения поддерева реализовывать именно так?

Ещё у меня начинаются какие-то проблемы с фильтрацией...

Если кто знает как это делается, прошу помощи. Или подскажите где посмотреть :)

★★
Ответ на: комментарий от grondek

Не, этот вариант не катит. Конечно, я про него знаю.

i82 ★★
() автор топика

Создание корректных проски-моделей непростая вещь. Исходники того же QSortFilterProxy - сложновоспринимаемая портянка на несколько тысяч строк. Смотреть, безусловно, можно как раз туда.

На первый взгляд в mapFromSource нужно сделать проверку, находится ли подсунутый тебе индекс в твоем поддереве, и если нет, то вернуть невалидный индекс. Если же находится, можно воспользоваться тем же QSortFilterProxyModel::mapFromSource. А вот как осуществить эту проверку, вопрос куда интереснее. Простейшее решениие, которое пришло мне в голову - пройтись по parent'ам от переданного индекса вверх, пока не достигнешь своего корневого элемента или корневого элемента оригинальной модели. Но по очевидным причинам этот метод довольно скверный.

m0rph ★★★★★
()
Ответ на: комментарий от m0rph

Я правильно понимаю, что в простейшем случае, речь о чём-то таком:

QModelIndex TRDeviceFilterModel::mapFromSource(const QModelIndex &sourceIndex) const
{
	QModelIndex idx = sourceIndex;

	while (idx.isValid()) {
		if (idx == m_root)
			return QSortFilterProxyModel::mapFromSource(sourceIndex);
		idx = idx.parent();
	}

	return QModelIndex();
}

?

i82 ★★
() автор топика
Ответ на: комментарий от i82

Да, именно это я и имел в виду. Только не гарантирую результат, я всего лишь высказал некоторые соображения. Кстати, в идеале хорошо бы добавить проверку, что sourceIndex.model() == sourceModel(), а то чисто технически тебе могут подсунуть вообще непонятно что.

m0rph ★★★★★
()
Ответ на: комментарий от m0rph

С идеалом буду разбираться потом, как только всё что хочу _пойму_ как сделать и сделаю. Сейчас не могу понять, почему при фильтрации в моей прокси-модели с реализованной логикой subtree у меня пустые строки появляются. Фильтрую так (с учётом вложенных элементов):

bool TRDeviceFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
	if (QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent))
		return true;

	QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
	for (int row = 0, rows = sourceModel()->rowCount(idx); row < rows; row++) {
		if (filterAcceptsRow(row, idx))
			return true;
	}

	return false;
}

Wtf?

i82 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.