LINUX.ORG.RU

Отмена сортировки через прокси-модель

 , ,


0

1

Добрый день.

Есть у меня табличная модель, наследница QAbstractTableModel. Отображается через QTableView. Захотелось мне ещё сортировку сделать. Написал наследника QSortFilterProxyModel, подключил. Вызвал у QTableView setSortingEnabled - сортировка работает.

Но хочется мне, чтобы сортировку можно было включать и отключать. И вот тут какие-то непонятки. Вызываю у view setSortingEnabled(true) - сортировка сразу включилась, появились значки в заголовке, работают. Вызываю setSortingEnabled(false) - значки вроде бы пропали, но View по-прежнему показывает данные в отсортированном порядке.

Там надо ещё что-то вызвать?

Нет, есть ещё конечно, как минимум два «лобовых» варианта:

  • при отключении сортировки просто выбрасывать прокси-модель и во view работать напрямую с оригиналом. При включении - восстанавливать цепочку. Но кажется мне, что это явно черезжопно по коду. Хотя тормоза на ненужную сортировку гарантированно исключает;
  • чуть усложнить lessThan в прокси-модели, чтобы при отключённой сортировке оно просто работало как предок. Код компактнее, но во-первых, сортировка, хоть и вырожденная, всё равно будет дёргаться, а во-вторых меня не покидает ощущение, что должен быть какой-то бескостыльный вариант. А этот всё равно костыльный, хоть и не настолько, как первый...
★★★★★

Последнее исправление: hobbit (всего исправлений: 1)

Отображается через QTableView. Захотелось мне ещё сортировку сделать

Для сортировки достаточно сделать setSortingEnabled(), оно работает без модели-посредника. Если ты вызовешь setSortingEnabled(false), ты лишь запретишь виджету сортировать содержимое. Модель-посредник же сортирует данные независимо от настроек виджета

XMs ★★★★★
()

Первый вариант вовсе не черезжопный - как по мне, именно так это и должно работать. setModel на прокси/оригинал.

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

ЕМНИП, типы, сводимые к qreal, также могут сортироваться средствами виджета. Про сложные типы не знаю, не сталкивался

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

Для сортировки достаточно сделать setSortingEnabled(), оно работает без модели-посредника. Если ты вызовешь setSortingEnabled(false), ты лишь запретишь виджету сортировать содержимое. Модель-посредник же сортирует данные независимо от настроек виджета

Что-то мои эксперименты этого не подтверждают. Если не тащить прокси-модель, а просто вызвать setSortingEnabled(true), у view появятся значки сортировки, но данные выводятся несортированными. Если же, наоборот, подключить посредника, данные отсортируются, но только после того, как я вызову setSortingEnabled(true).

Да, справка по setSortingEnabled() ничего про посредников не говорит. Там написано, что Setting the property to true with setSortingEnabled() immediately triggers a call to sortByColumn() with the current sort section and order. Но не понятно, где эти current sort section and order задаются.

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

появятся значки сортировки, но данные выводятся несортированными

А если после этого нажать на значки сортировки? У меня сортировка всегда работала без посредников, после нажатия

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

Вот этот код сортирует сразу и работает без модели-посредника:

#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QDateTime>
#include <QtGlobal>



void fillModel(QStandardItemModel &model);

int main(int argc, char **argv)
  {
	QApplication app(argc, argv);

	QStandardItemModel model;
	fillModel(model);

	QTableView view;
	view.setSortingEnabled(true);
	view.setModel(&model);
	view.sortByColumn(0, Qt::AscendingOrder);
	view.show();

	return app.exec();
  }


void fillModel(QStandardItemModel &model)
  {
	const int COLS = 10,
	          ROWS = 100;

	qsrand(QDateTime::currentDateTime().toTime_t());

	for (int row = 0; row < ROWS; row++)
	  {
		QList<QStandardItem*> items;
		for (int col = 0; col < COLS; col++)
		  {
			QStandardItem *item = new QStandardItem;
			item->setData(qrand() % 100, Qt::DisplayRole);
			items << item;
		  }
		model.appendRow(items);
	  }
  }

XMs ★★★★★
()

setSortingEnabled() это вообще из другой оперы, оно просто позволяет пользователю кликать на заголовках таблицы. Если пользователь уже отсортировал, то setSortingEnabled(false) просто запретит ему кликнуть, на отображение же оно не влияет.

А если внимательней прочитать мануал:

QSortFilterProxyModel can be sorted by column -1, in which case it returns to the sort order of the underlying source model.

Dendy ★★★★★
()
Последнее исправление: Dendy (всего исправлений: 1)
Ответ на: комментарий от Dendy

QSortFilterProxyModel can be sorted by column -1, in which case it returns to the sort order of the underlying source model.

Спасибо, вот это помогло. После отмены сортировки явно вызываю sort(-1).

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

Нет, с моей моделью такое не работает. Может, это потому, что в примере QStandardItemModel? Там же уже sort переопределённый...

В любом случае проблема решена, как - см. комментарий выше.

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