Russian Qt Forum
Апрель 29, 2024, 22:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Сортировка в модели  (Прочитано 16196 раз)
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« : Август 26, 2007, 18:07 »

В общем все началось давным давно....  Улыбающийся
Использую QStandardItemModel и QTreeView, загоняю в модель имена файлов, расширения, даты, в общем самодельный файловый менеджер. Понадобилась сортировка, после прочтения форума понял, что нужно действовать через QSortFilterProxyModel. После прочтения ассистента пришел к такой связке:
1. Наследую класс QSortFilterProxyModel.
2. Переписываю lessThan.
3. Подключаю QStandardItemModel к QSortFilterProxyModel.
4. Подключаю QSortFilterProxyModel к QTreeView.
Собственно несколько вопросов:
1. Праильно ли сделано, просто какое-то очень неудобное подключение модели через модель. Улыбающийся
2. Как сделать дирректории всегда вверху? Т.е. тут вопрос в том, где достать тип сортировки(сверху вниз или наоборот). Искал в модели, но там это встречается только в sort, но переопределяя эту функцию я гроблю всю сортировку. Грустный
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
vaprele07
Гость
« Ответ #1 : Август 27, 2007, 01:33 »

Код:
bool QSortFilterProxyModel::lessThan ( const QModelIndex & left, const QModelIndex & right ) const 
{
  ...
  if (leftType != rightType) return (leftType == dir); // или return (leftType == file); вверх-вниз
    else return QString::localeAwareCompare(leftString, rightString) < 0;
}

Забыл: насчёт первого да правильно QStandardItemMode это как БД, а QSortFilterProxyModel как SQL запрос
« Последнее редактирование: Август 27, 2007, 01:46 от vaprele07 » Записан
denka
Гость
« Ответ #2 : Август 27, 2007, 09:38 »

А почему не воспользовался QDirModel там и сортировка вроде как есть и филтры?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Август 27, 2007, 11:38 »

Код:
bool QSortFilterProxyModel::lessThan ( const QModelIndex & left, const QModelIndex & right ) const 
{
  ...
  if (leftType != rightType) return (leftType == dir); // или return (leftType == file); вверх-вниз
    else return QString::localeAwareCompare(leftString, rightString) < 0;
}

Забыл: насчёт первого да правильно QStandardItemMode это как БД, а QSortFilterProxyModel как SQL запрос
Этот код есть в ассисетнте. Вопрос был в другом: как узнать ТЕКУЩИЙ тип сортировки (вверх-вниз)? Ваш код работать не будет, так как дирректории будут или все вверху, или все внизу.
А почему не воспользовался QDirModel там и сортировка вроде как есть и филтры?
Во-первых недавно я поднимал вопрос о баге с pagefile.sys, а во-вторых скорость загрузки не устраивает и еще кое какие мелочи.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Emc
Гость
« Ответ #4 : Август 27, 2007, 12:02 »

собственная сортировка устанавливается через setSortRole()
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #5 : Август 27, 2007, 12:11 »

собственная сортировка устанавливается через setSortRole()
На сколько я понял из ассистента, setSortRole() к этому никаким боком не относится. Посмотри значения enum Qt::ItemDataRole там ничего о порядке сортировки.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
vaprele07
Гость
« Ответ #6 : Август 27, 2007, 13:38 »

Поряд собственной сортировки что и когда ты задаешь сам путем переопределения lessThan
if (leftType != rightType) return (leftType == dir); // или return (leftType == file); вверх-вниз
в этой строчке ты сортируешь индексы по типам т.е. если типы не совпадают значит что-то из двух файл, а что-то папка при этом return (leftType == dir) директории вверху, при этом return (leftType == file) внизу, если типы совпадают то выполняется:
else return QString::localeAwareCompare(leftString, rightString) < 0; здесь может быть любая другая функция сравнения хоть по дате хоть по мимэ типу...
setSortRole() сортировка по ролям, допустим нужно тебе сортировать по тултипам, статустипам, декорациям.

кстати если тебе нужна сортировка типа папка-файл вверх-вниз без изменения стандартной логики:

Код:
bool MySortFilterProxyModel::lessThan ( const QModelIndex & left, const QModelIndex & right ) const 
{
  ...
  if (leftType != rightType) return (leftType == (MySortType == dirAbove)?dir:file);
    else return QSortFilterProxyModel::lessThan(left, right);
}
« Последнее редактирование: Август 27, 2007, 13:40 от vaprele07 » Записан
Emc
Гость
« Ответ #7 : Август 27, 2007, 14:00 »

setSortRole() относится к этому напрямую
самый примитивный вариант, создаешь собственную роль - в случае папки MyRole = "AAA_+DisplayRole" в случае файла MyRole = "DisplayRole".
//
setSortRole(MyRole);
sort(0);
//
собственно всё
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #8 : Август 27, 2007, 16:52 »

Да я не об этом. Есть колонка имен с номером 0. Щелкаем по ней один раз и сортировка происходит по возрастанию, щелкаем второй - по убыванию. Мне нужно знать, по возрастанию или убыванию сортировка, потому что lessThan в разных случаях интерпретируется по разному, т.е. логически умножается на порядок сортировки.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #9 : Август 27, 2007, 17:54 »

Вот ответ, наверное. Завтра буду копать.
http://websvn.kde.org/trunk/KDE/kdelibs/kfile/kdirsortfilterproxymodel.cpp
http://websvn.kde.org/trunk/KDE/kdelibs/kfile/kdirsortfilterproxymodel.h
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #10 : Август 28, 2007, 11:26 »

Облом. Все не то. Вот мой код:
Код:
QVariant UpData = sourceModel()->data(sourceModel()->index(qmiUp.row(),2));
QVariant DownData = sourceModel()->data(sourceModel()->index(qmiDown.row(),2));

if ((UpData.toString()=="-=DIR=-") && (DownData.toString()!="-=DIR=-"))
{
return true;
}
else
if ((UpData.toString()!="-=DIR=-") && (DownData.toString()=="-=DIR=-"))
{
return false;
}
В итоге папки отдельно от файлов, но то вверху, то внизу. Решением послужило бы
Код:
QVariant UpData = sourceModel()->data(sourceModel()->index(qmiUp.row(),2));
QVariant DownData = sourceModel()->data(sourceModel()->index(qmiDown.row(),2));

if ((UpData.toString()=="-=DIR=-") && (DownData.toString()!="-=DIR=-"))
{
return true && order;
}
else
if ((UpData.toString()!="-=DIR=-") && (DownData.toString()=="-=DIR=-"))
{
return false && order;
}
Где order есть Qt::SortOrder (AscendingOrder или DescendingOrder). Но как этот order достать?Непонимающий?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
denka
Гость
« Ответ #11 : Август 29, 2007, 10:00 »

Можно так:
Код:
class MySortModel : public QSortFilterProxyModel
{
public:
MySortModel( QObject * parent = 0 );
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;
void sort( int column, Qt::SortOrder order = Qt::AscendingOrder );
private:
Qt::SortOrder m_order;
};
Код:
void MySortModel::sort( int column, Qt::SortOrder order )
{
m_order = order;
QSortFilterProxyModel::sort( column, order );
}
Код:
bool MySortModel::lessThan( const QModelIndex &l, const QModelIndex &r ) const
{
...
if ( ltype == rtype )
return QString::localeAwareCompare( lname, rname ) < 0;
else if ( ltype == "dir" )
return m_order == Qt::AscendingOrder;
return m_order != Qt::AscendingOrder;
}

ltype и rtype это или каталог или файл, соответственно левый и правый индекс Улыбающийся
« Последнее редактирование: Август 29, 2007, 10:08 от den'ka » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #12 : Август 29, 2007, 11:34 »

А ты пробовал этот код? Просто у меня он не заработал. Из sort ты вызываешь QSortFilterProxyModel::sort( column, order ); но QSortFilterProxyModel - это не твоя модель, и lessThan у нее соответсвенно не твой. Грустный
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
denka
Гость
« Ответ #13 : Август 29, 2007, 11:43 »

У меня все работает. Правда я не пользовался QStandardItemModel, но ведь это не меняет дела. Если хочеш вышлю на мыло исходники.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #14 : Август 29, 2007, 11:46 »

Буду очень рад.
panter.dsd@gmail.com
Только можешь в ближайшие 10 минут кинуть, а то на работу...
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.135 секунд. Запросов: 22.