Russian Qt Forum

Qt => Дополнительные компоненты => Тема начата: shade-khv от Декабрь 08, 2008, 10:35



Название: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: shade-khv от Декабрь 08, 2008, 10:35
Я тут заметил что достаточно часто спрашивают про QTableView, сравнивая его с DbGridEh. В основном по части многоуровневых заголовков и сортировки по нескольким столбцам. Причем готовых решений никто в ответах не предлагает, а просто пишут наследовать QHeaderView, либо пишут что решение есть, но оно очень привязано к определенному проекту. В общем я некоторое время потратил на "прокачку" таблицы и реализовал сортировку по многим столбцам. Архив с проектом здесь: http://slil.ru/26411453 (это несколько модифицированный стандартный пример Qt).

Если вы его соберете, то заметите что работает он не совсем так как DbGridEh. В DbGridEh при щелчке по столбцу вся прежняя сортировка сбрасывается, а при нажатии Shift и щелчке по столбцу этот столбец добавляется в порядок сортировки. Собственно вопрос в том как в методе NSHeaderView::processHeadClick определить нажат ли Shift, чтобы допилить функциональность сортировки до DbGridEh.

Кстати, если кто нибудь знает бесплатный аналог DbGridEh для Qt, подскжите плиз, а то может я велосипед изобретаю?


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: EhTemka от Декабрь 09, 2008, 16:13
Проект не смотрел, но есть вот это
QApplication::keyboardModifiers() & Qt::ShiftModifier.

Модераторам : имхо, вопрос немного не для этого раздела.


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: shade-khv от Декабрь 10, 2008, 02:53
Спасибо, попробую.
А в какую тему лучше было бы написать?


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: shade-khv от Декабрь 10, 2008, 03:12
EhTemka, еще раз спасибо, все работает. А вы случайно с EhLib никак не связаны? :)

Если кто то будет использовать классы из моего проекта, то перепишите метод NSHeaderView::processHeadClick так:

Код
C++ (Qt)
void NSHeaderView::processHeadClick( int logicalIndex )
{
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
   {
   if (!sortOrder.contains(logicalIndex)) {setSortIndicator (logicalIndex, Qt::AscendingOrder ); sortOrderNums.append(logicalIndex);}
   else if (sortOrder[logicalIndex]==Qt::AscendingOrder) {sortOrder.remove(logicalIndex); sortOrderNums.removeOne(logicalIndex);}
   }
else
   {
   sortOrder.clear(); sortOrderNums.clear();
   setSortIndicator (logicalIndex, Qt::AscendingOrder); sortOrderNums.append(logicalIndex);
   }
sortmodel->sort(0);
}

и сортировка будет работать так же как в DbGridEh.


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: ритт от Декабрь 10, 2008, 07:17
shade-khv, лучшее место для данной ветки - раздел "дополнительные компоненты" - можешь создать там новую тему, а ту, видимо, можно похерить. и было бы совсем хорошо, если бы ты прикрепил проект к самой ветке, а то слил.ру - как-то некузяво...


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: Racheengel от Декабрь 10, 2008, 15:20
а на qt-apps есть желание забросить?


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: shade-khv от Декабрь 11, 2008, 04:01
Не уверен что куда то стоит забрасывать пока потому что мне было некогда нормально наследовать и переписывать приватную часть QSortFilterProxyModel, поэтому в NSSortFilterProxyModel используется QSortFilterProxyModelPrivate. Не уверен что это корректно. Вообще не уверен что полностью разобрался как корректно наследовать в Qt.

Тем более что и отзывов то о ней нет. У меня работает, а у других? Я думал выложу - люди потестят, отпишутся.


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: EhTemka от Декабрь 15, 2008, 13:28
Цитировать
Не уверен что куда то стоит забрасывать пока потому что мне было некогда нормально наследовать и переписывать приватную часть QSortFilterProxyModel, поэтому в NSSortFilterProxyModel используется QSortFilterProxyModelPrivate. Не уверен что это корректно. Вообще не уверен что полностью разобрался как корректно наследовать в Qt.

А что ты изменил в QSortFilterProxyModelPrivate?


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: shade-khv от Декабрь 16, 2008, 04:33
Если честно, по моему только
    Q_DECLARE_PUBLIC(NSSortFilterProxyModel)
    Q_Q(NSSortFilterProxyModel);


И в class QSortFilterProxyModelLessThan изменил

private:
    const NSSortFilterProxyModel *proxy_model;


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: EhTemka от Декабрь 22, 2008, 11:20
ПОсмотрел бегло той код.

Собственно смущают две вещи:

1. Зачем использовать приватный класс? Веть он на то и приватный. Троли имеют право переписывать его от версии к версии как угодно. Таким образом с большой вероятностью твои наработки не будут работать на других версиях Qt, или же работать некорректно. И вообще не очень понятна надобность энтого, вполне можно обойтись предоставленным Qt интерфейсом.

Если тебе нужен функционал QSortFilterProxyModel в функциях которые ты у него перегружаешь, то и вызывай их.
Например так
Код:
QVariant NSSortFilterProxyModel::data(const QModelIndex &index, int role) const
{
    // это
    QVariant data = QSortFilterProxyModel::data(index, role);
   
    // вместо этого
/*
    Q_D(const QSortFilterProxyModel);
    QModelIndex source_index = mapToSource(index);
    if (index.isValid() && !source_index.isValid())
        return QVariant();
   
    QVariant data = d->model->data(source_index, role);
*/

    if (data.type()==QVariant::Bool)
    {
    if (data.toString()=="true") return QVariant("Да");
    if (data.toString()=="false") return QVariant("");
}

    return data;
}

2. Ты перегружаешь некоторые функции. Во первых почему ты убираешь ключевое слово virtual? Подразумевается, что больше нельзя будет ее перегружать в наследниках? Почему?
Во вторых - зачем менять модификаторы доступа к этим функциям.
Например  функция bool QSortFilterProxyModel::lessThan ( const QModelIndex & left, const QModelIndex & right ) const  [virtual protected]
была protected и виртуальная, а стала public и невиртуальная.





Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: ритт от Декабрь 22, 2008, 11:52
EhTemka,
1. прав - большинство членов привата QSortFilterProxyModel доступны через публичную часть (есть исключения, но сейчас не о них)
2. низачОт


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: EhTemka от Декабрь 22, 2008, 12:14
EhTemka,
1. прав - большинство членов привата QSortFilterProxyModel доступны через публичную часть (есть исключения, но сейчас не о них)
2. низачОт

По второму пункту поясните...


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: ритт от Декабрь 22, 2008, 13:21
попробуй
Код:
class A
{
public:
  virtual ~A
  {}

  virtual int testfunc()
  { return 0; }
}

class B : public A
{
public:
  int testfunc()
  { return 1; }
}

class C : public B
{
public:
  int testfunc()
  { return 2; }
}


Название: Re: Сделал таблицу с сортировкой по нескольким столбцам
Отправлено: EhTemka от Декабрь 22, 2008, 14:43
Да, век живи, век учись  :)
Но все-таки virtual я бы написал, потому как сразу было бы понятно, что эта функция виртуальна, чтобы не рыскать на этот счет в предках (коих может быть несметное количество).