Обновление индикатора порядка сортировки в QTableView/QHeaderView при сортировке модели

Я хочу знать, как обеспечить обновление индикатора сортировки в горизонтальном заголовке QTableView при выполнении программной сортировки модели.

Вот проблема:

QStandardItemModel model(3,1);
QTableView view;
view.setModel( &model );

// Populate the model ensuring it is not in a sorted order
for( int row = 0; row < model.rowCount(); ++row )
{
    model.setItem( row , 0 ,
                   new QStandardItem(QString::number((row+1)%model.rowCount())));
}

view.setSortingEnabled( true );
// At this point everything is consistent since enabling the sorting
// triggers a sort that matches the indicator in the horizontalHeader (see A)

model.sort( 0 , Qt::AscendingOrder );
// However at this point the sort order has been reversed but the
// header's sort indicator remains unchanged (see B)

A: A: сразу после setSortingEnabled(true)B:Сразу после model.sort(0,Qt::AscendingOrder)

Как видите, индикатор сортировки остается прежним и, следовательно, не соответствует фактическому порядку сортировки.

В моем приложении у меня есть два представления, которые взаимодействуют с одной и той же моделью, и сортировка может быть запущена из любого из них. Я не вижу в QAbstractItemModel ничего, что сигнализировало бы о выполнении сортировки. Похоже, что QHeaderView/TableView предполагают, что это единственное, что может вызвать сортировку.

Предоставляет ли Qt средства для решения этой проблемы, которую мне не хватает? Если нет, то как лучше всего поддерживать индикатор сортировки в актуальном состоянии, не нарушая слишком сильно инкапсуляцию нескольких представлений модели?


person SimonD    schedule 02.06.2014    source источник
comment
Я думаю, что инициатором сортировки должно быть скорее представление, чем модель. Поэтому вы можете использовать функцию QTableView::sortByColumn(), которая, IMO, также должна устанавливать индикатор сортировки.   -  person vahancho    schedule 02.06.2014
comment
Спасибо @vahancho. В моем приложении пользователь может инициировать сортировку из одного из двух представлений. Я хочу, чтобы индикатор сортировки в табличном представлении правильно синхронизировался в этом случае. Я надеялся сделать это без прямого взаимодействия представлений друг с другом...   -  person SimonD    schedule 02.06.2014
comment
Если это так, вместо вызова sort() вашей модели вы можете вызывать QTableView::sortByColumn() для каждого из ваших представлений.   -  person vahancho    schedule 02.06.2014
comment
Но это приведет к многократной сортировке модели, не так ли? Также требуется, чтобы каждое представление «знало» о других представлениях, что несколько нарушает инкапсуляцию: не все представления будут существовать постоянно.   -  person SimonD    schedule 02.06.2014


Ответы (2)


Один из перечислителей ItemDataRole, доступных начиная с Qt 4.8, — это InitialSortOrderRole.

http://qt-project.org/doc/qt-4.8/qt.html#ItemDataRole-enum

Поэтому должна быть возможность передавать информацию о порядке сортировки с помощью метода QAbstractItemModel::headerData.

Однако я попробовал это и обнаружил, что QTableView и QHeaderView, похоже, не обновляются в ответ на изменения в этой роли headerData. Казалось бы, необходим индивидуальный вид заголовка...

Возможно, это того стоит, потому что передача этой информации через модель позволяет синхронизировать любое количество представлений без необходимости какого-либо внешнего агента отслеживать все существующие представления, чтобы он мог распространять уведомления. Он также будет без проблем работать через стеки прокси-серверов моделей, например, созданные с помощью QSortFilterModelProxy.

person SimonD    schedule 03.06.2014

Решение, которое я придумал, чтобы избежать слишком сильного нарушения инкапсуляции,

  • чтобы иметь сигнал на каждом представлении (на QTableView достаточно сигнала sortIndicatorChanged, и в моем пользовательском представлении я добавил аналогичный сигнал).
  • менеджер просмотров connects на эти сигналы
  • когда какое-либо представление излучает такой сигнал, менеджер представлений вызывает слот для всех других представлений, чтобы они могли синхронизировать свои индикаторы сортировки.

Я все еще чувствую, что могу что-то упустить — наверняка это распространенная проблема? Мне кажется, что QAbstractItemModel должен иметь способ передачи информации о порядке сортировки представлениям...

person SimonD    schedule 03.06.2014