Russian Qt Forum

Qt => Вопросы новичков => Тема начата: CJ1 от Октябрь 03, 2012, 11:37



Название: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 11:37
Вобщем есть 3 столбца.
Нужно сделать сортировку так.
Сперва первый столбец сортируется так.
Если идет слово казахстан. То он на первое место встает, потом если идет слово Россия то она становится на второе место, а остольное по алфавиту.
Затем в третьем столбце сортируется так, все что относится к казахстану сортируется по алфавиту, потом Все что относится к России сортируется по алфавиту в третьем столбике,
Никак не могу придумать алгоритм...


И еще... Как можно из QString например такого 111\r\n222
Сделать QStringList
  • 111
  • [2] 222


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: Sancho_s_rancho от Октябрь 03, 2012, 11:41
Вобщем есть 3 столбца.
Нужно сделать сортировку так.
Сперва первый столбец сортируется так.
Если идет слово казахстан. То он на первое место встает, потом если идет слово Россия то она становится на второе место, а остольное по алфавиту.
Затем в третьем столбце сортируется так, все что относится к казахстану сортируется по алфавиту, потом Все что относится к России сортируется по алфавиту в третьем столбике,
Никак не могу придумать алгоритм...
Я знаю как поставить Россию на первое место, а Казахстан на второе, а все остальное по алфавиту. А вот Казахстан на первое - это невозможно  ;D
PS отсортируй все по алфавиту, а потом просто добавь эти два слова в том порядке,  в котором надобно


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: mutineer от Октябрь 03, 2012, 11:42
Ну по поводу первого столбца все просто - Казахстан меньше любых значений, Россия меньше всех, кроме Казахстана, а остальные значения сравниваются по обычным правилам


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: Igors от Октябрь 03, 2012, 11:45
Был точно такой же вопрос, поищите напр "Казахстан"


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: mutineer от Октябрь 03, 2012, 11:47
И еще... Как можно из QString например такого 111\r\n222
Сделать QStringList
  • 111
  • [2] 222
QString::split()


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 11:47
Не такой... Там только сортировка по первому столбику
А мне нужно чтоб в добавок и по третему


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 12:01
Вот такой код работает почти правильно!
Код
C++ (Qt)
bool ItemSort::operator< ( const QTableWidgetItem & other ) const
{
       if( (this->column() == 0 && other.column() == 0 && other.row() > 0 && this->row() >0))
       {
 
           if( this->text().toLower().trimmed().startsWith( "каз" )|| this->text().toLower().trimmed().startsWith( "кз" ))
               return true;
           if( other.text().toLower().trimmed().startsWith( "каз" )|| other.text().toLower().trimmed().startsWith( "кз" ))
               return false;
 
           if( this->text().toLower().trimmed().startsWith( "рос" )|| other.text().toLower().trimmed().startsWith( "рф" ))
               return true;
           if( other.text().toLower().trimmed().startsWith( "рос" )|| other.text().toLower().trimmed().startsWith( "рф" ))
               return false;
       }
   return false;//QTableWidgetItem::operator<( other );
}
 

Но третий столбик не сортируется


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: mutineer от Октябрь 03, 2012, 12:16
Да и первый после России вряд ли по алфавиту сортируется


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 12:22
сортируются.
Ну вообще в какую сторону копать чтоб сортировать по двум столбцам?


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: mutineer от Октябрь 03, 2012, 12:26
Можешь покопать в сторону model/view и QSortFilterProxyModel


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 12:53
Понял! Сперва сортирую по 3 столбику а потом по первому
                ItemSort * it = new ItemSort();
                tables->setItemPrototype(it);
                tables->sortItems(2,Qt::DescendingOrder);
                tables->sortItems(0);


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 13:14
не не то!


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: Igors от Октябрь 03, 2012, 13:29
Начало кода возьмете из летней темы.

Код
C++ (Qt)
//  if (pr1 < pri_Default) return false;
//  return QTableWidgetItem::operator< (other);
 
// заменить на
QTableWidgetItem * itm1 = tableWidget()->itemAt(row(), 3);
QTableWidgetItem * itm2 = tableWidget()->itemAt(other.row(), 3);
return *itm1 < *itm2;
 
И проверки на "рф", регистр и др. вынесите в ф-цию GetPriority, не разводите свинарник


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 13:31
Я не совсем понял, модно по подробнее?


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 13:49
Вот сделал!
Вообще не сортирует!
Код
C++ (Qt)
bool ItemSort::operator< ( const QTableWidgetItem & other )const
{
 
    if (this->row() == 0){
        return false;
 
    }
    if (other.row() == 0) {
        return false;
    }
    int pr1 = GetPriority(*this);
    int pr2 = GetPriority(other);
    if (pr1 > pr2) return false;
    if (pr1 < pr2) return true;
 
    QTableWidgetItem * itm1 = _table->itemAt(2,row());
    QTableWidgetItem * itm2 = _table->itemAt(2,other.row());
    return *itm1 < *itm2;
 
 
}
 
 
И еще мне надо строчку 0 исключить из сортировки!


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 14:12
Ну помогите пожалуста!


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: Igors от Октябрь 03, 2012, 14:23
И еще мне надо строчку 0 исключить из сортировки!
Наверное имеется ввиду "поставить первой". Тогда Вы это сделали неправильно. Проверьте без этих изменений. Если и без них не работает - выложите проект


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 14:30
У меня получилось!
Сделал так
Код
C++ (Qt)
enum {
pri_Kazah,
pri_Russia,
pri_Default,
};
 
inline int GetPriority( const QTableWidgetItem & itm )
{
  if (itm.text().toLower().trimmed().startsWith( "каз" )|| itm.text().toLower().trimmed().startsWith( "кз" ))  return pri_Kazah;
  if (itm.text().toLower().trimmed().startsWith( "рос" )|| itm.text().toLower().trimmed().startsWith( "рф" ))  return pri_Russia;
  return pri_Default;
}
 
bool ItemSort::operator< ( const QTableWidgetItem & other )const
{
 
    if (this->row() == 0){
        return false;
 
    }
    if (other.row() == 0) {
        return false;
    }
    if (other.column() == 0 && this->column() == 0) {
       int pr1 = GetPriority(*this);
       int pr2 = GetPriority(other);
       if (pr1 > pr2) return false;
       if (pr1 < pr2) return true;
 
       return QTableWidgetItem::operator< (other);
    }
 
    return QTableWidgetItem::operator< (other);
 
 
}

А потом
Код
C++ (Qt)
               ItemSort * it = new ItemSort(tables);
 
               tables->setItemPrototype(it);
               tables->sortItems(2);
               tables->sortItems(0);


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 14:30
Цитировать
Проверьте без этих изменений

Без изменений первая строчка бегает


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: Igors от Октябрь 03, 2012, 16:32
А потом
Код
C++ (Qt)
               ItemSort * it = new ItemSort(tables);
 
               tables->setItemPrototype(it);
               tables->sortItems(2);
               tables->sortItems(0);
 
Так будет по именам нулевого столбца, а не 2-го  :)

Код
C++ (Qt)
inline int GetPriority( const QTableWidgetItem & itm )
{
  if (itm.text().toLower().trimmed().startsWith( "каз" )|| itm.text().toLower().trimmed().startsWith( "кз" ))  return pri_Kazah;
  if (itm.text().toLower().trimmed().startsWith( "рос" )|| itm.text().toLower().trimmed().startsWith( "рф" ))  return pri_Russia;
  return pri_Default;
}
 
О таком тексте говорят "писал не ленивый программист"  :)


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 17:14
Код:
Так будет по именам нулевого столбца, а не 2-го  

Нет, именно так мне и нужно!
Он по обоим столбцам сортирует


Код:
О таком тексте говорят "писал не ленивый программист"  

А как по другому?


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: Igors от Октябрь 03, 2012, 17:27
А как по другому?
Хотя бы так
Код
C++ (Qt)
inline int GetPriority( const QTableWidgetItem & itm )
{
  if (itm.row() == 0) return pri_Row0;
  QString txt = itm.text().toLower().trimmed();
  if (txt.startsWith( "каз" )|| txt.startsWith( "кз" ))  return pri_Kazah;
  if (txt.startsWith( "рос" )|| txt.startsWith( "рф" ))  return pri_Russia;
  return pri_Default;
}
 

Нет, именно так мне и нужно!
Он по обоим столбцам сортирует
Он сортирует сначала по одному, потом по другому, поэтому в общем случае результаты первой сортировки утеряны


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: CJ1 от Октябрь 03, 2012, 18:01
Смотри. Вот мне нужно было так.
Допустим рассортировал он столбец 0.
Сначало выходят все Казахстан.
Вот потом он делает сортировку по третему столбцу но именно до казахстан и так далее
Пример


Казахстан    Ам
Казахстан    Ар
Казахстан    Бы
Казахстан    Си
Казахстан    т
Россия       ААА
Россия       ма
Россия       но
Россия       при
Россия       яв


Название: Re: Помогите с сортировкой QTableWidget
Отправлено: VPS от Октябрь 03, 2012, 18:20
Советую посмотреть книгу Бланшет,Саммерфилд - "QT4 Программирование GUI на С++".
Там есть пример создания приложения электронной таблицы с возможностью групповой сортировки (глава 3 -> spreadsheet )...
Я думаю, что можно и под Ваши требования переделать...

Дополнение:
Если отталкиваться от того примера, то можно попробовать  добавить ещё один унарный предикат, для алгоритма std::partition, в котором для названий стран "Казахстан" и "Россия" возвращать true.
Потом в методе sort класса Spreadsheet вместо простого вызова функции:
Код:
qStableSort(rows.begin(), rows.end(), compare);
сначала вызвать функцию std::partition, а уже затем для каждого поддиапазона вызывать qStableSort.