У меня есть модель, которая является подклассом из QAbstractListModel
, которая имеет разные представления списка, которые отфильтрованы с использованием подкласса QSortFilterProxyModel для каждого представления. Данные в представлении можно сортировать, когда пользователь нажимает кнопку сортировки.
Я реализовал перетаскивание внутри QSortFilterProxyModel, чтобы изменить состояние данных, когда они помещаются в новый список. Это отлично работает, однако ручная сортировка элементов в списке приводит к сортировке всех других списков, отображающих те же данные, а это не то, что я хочу.
Например, в представлении 1 показаны все участники, в представлении 2 показаны активные участники. При перетаскивании из вида 1 в вид 2 участник становится активным. Если я вручную отсортирую участников, индекс активных участников также будет отсортирован. Однако этого не происходит, если я автоматически сортирую их с помощью метода proxyModel->sort()
.
Как вручную изменить порядок данных в прокси-модели без изменения индекса в исходной модели?
Пример кода:
MySortFilterProxyModel::MySortFilterProxyModel(bool active, QObject *parent ) :
QSortFilterProxyModel( parent ),
m_filter( "" ),
m_active(active)
{
setDynamicSortFilter( false );
}
void MySortFilterProxyModel::setFilter( QString filter )
{
m_filter = filter;
invalidateFilter();
}
Qt::ItemFlags MySortFilterProxyModel::flags( const QModelIndex &index ) const
{
if( index.isValid() )
{
return ( QSortFilterProxyModel::flags( index ) | Qt::ItemIsDragEnabled | Qt::ItemIsEditable );
}
return Qt::ItemIsDropEnabled | QSortFilterProxyModel::flags( index );
}
bool MySortFilterProxyModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
{
if( !data->hasFormat( dataModel::dataMimeType() ) )
{
return false;
}
if( action == Qt::IgnoreAction )
{
return true;
}
if( column > 0 )
{
return false;
}
QByteArray encodeData = data->data(dataModel::dataMimeType());
QDataStream stream( &encodeData, QIODevice::ReadOnly );
while( !stream.atEnd() )
{
DataRecord *dr = new DataRecord();
stream >> dr;
dr->setActive( m_active );
// AddData method in the dataModel removes duplicate rows and inserts the data into the correct row.
qobject_cast< DataModel * >( sourceModel() )->addData( fdr, parent.row() );
}
return true;
}
Изменить addData() Возможно, есть лучший способ сделать это:
void DataModel::addData( DataRecord *dr, int row )
{
int i =0;
for( auto const& itr : m_dataRecords )
{
if( itr->getUniqueID() == dr->getUniqueID() )
{
break;
}
++i;
}
removeRows( i, 1, QModelIndex() );
beginInsertRows( QModelIndex(), row, row );
m_dataRecords.insert( row, dr );
endInsertRows();
}
В DataModel я также реализую следующие методы:
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
bool setData( const QModelIndex & index, const QVariant & value, int role=Qt::EditRole );
bool removeRows( int row, int count, const QModelIndex &parent ) override;
QMimeData *mimeData( const QModelIndexList &indexes ) const override;
QStringList mimeTypes() const override;
int rowCount( const QModelIndex &parent ) const override;
Qt::DropActions supportedDropActions() const override;
DataModel::addData
? - person IlBeldus   schedule 27.07.2017parent.row()
без родителяmapToSource()
и убедиться, что он действителен. - person IlBeldus   schedule 27.07.2017