Russian Qt Forum

Qt => Model-View (MV) => Тема начата: ритт от Декабрь 23, 2007, 09:20



Название: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: ритт от Декабрь 23, 2007, 09:20
пахнет, как бага/недочёт, но решил пока троллей не спамить и просить помощи здесь!
вопрос срочный...иначе придётся откатываться на н ревизий и делать как было - через ж...

наследуюсь от QSortFilterProxyModel и имплементирую виртуальный метод filterAcceptsColumn, который в QSortFilterProxyModel банально всегда возвращает правду:
Код:
#include <QtGui/QSortFilterProxyModel>

class SortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT

public:
SortFilterProxyModel(QObject* parent = 0) : QSortFilterProxyModel(parent) {}
virtual ~SortFilterProxyModel() {}

// в данном упрощённом примере ловлю хидерДату чтобы вовремя скрывать "нежелательные" столбцы
void SortFilterProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
{
disconnect(QSortFilterProxyModel::sourceModel(), SIGNAL(headerDataChanged(Qt::Orientation, int, int)), this, SLOT(invalidate()));

QSortFilterProxyModel::setSourceModel(sourceModel);

connect(QSortFilterProxyModel::sourceModel(), SIGNAL(headerDataChanged(Qt::Orientation, int, int)), this, SLOT(invalidate()));
}

protected:
virtual bool filterAcceptsColumn(int source_column, const QModelIndex& source_parent) const
{
return (source_column % 2 != 0);
}
};

затем что-то вроде
Код:
MySubclassedAbstractTableModel* m_model = new MySubclassedAbstractTableModel(this);
SortFilterProxyModel* m_proxyModel = new SortFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);
QTableView* m_tableView = new QTableView(this);
tableView->setModel(m_proxyModel);
tableView->setSortingEnabled(true);

итого: показали вьюху, заполнили модельку данными, видим только нечётные столбцы исходной модели. и вьюха уверена, что никаких других столбцов нет.
теперь попробум выполнить сортировку на первом столбце - должно работать. а на столбце после первого?

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


Название: Re: [4.3.3] QSortFilterProxyModel, filterAcceptsColumn, QTableView и сортировка
Отправлено: Alex03 от Декабрь 23, 2007, 12:10
....
итого: показали вьюху, заполнили модельку данными, видим только нечётные столбцы исходной модели. и вьюха уверена, что никаких других столбцов нет.
теперь попробум выполнить сортировку на первом столбце - должно работать. а на столбце после первого?

прокся, хоть и попрятала столбцы по щучьему велению, а нормально маппиться не хочет, собака. и сижу мозг ломаю как ей доказать, что не по тому столбцу сортирует!
возможно, я в изобретатели велосипедов подался, но, вроде, прокся для того и нужна, чтобы что-то прятать и переворачивать
Т.е. сортируется по столбцу исходной модели?
Скорее это бага QSortFilterProxyModel, ибо вьюха ниче не знает про модель и по честному передаёт ей столбец.
Как вариант выхода в своём SortFilterProxyModel переопределить sort() на чтото типа
Код:
SortFilterProxyModel::sort(int column, Qt::SortOrder order)
{
    QSortFilterProxyModel::sort(filterColumnToSourceColumn(column), order);
}
ну и определить эту filterColumnToSourceColumn()
Код:
int SortFilterProxyModel::filterColumnToSourceColumn(filterColumn)
{
    if(filterColumn < 0)
        return filterColumn;

    for(int n=-1, nSourceColumn=-1; n<filterColumn;)
    {
        if(___valid___(++nSourceColumn))
            n++;
    }

    return sourceColumn;
}
Ну а  ___valid___(х) в Вашем случае (x % 2 != 0)

легко мог ошибиться гденить.


Название: Re: [4.3.3] QSortFilterProxyModel, filterAcceptsColumn, QTableView и сортировка
Отправлено: ритт от Декабрь 23, 2007, 12:24
спасибо за ответ

бага, однозначно! тролли минимум в трёх методах не ремаппят прокси_колумн на сёрч_колумн, из-за чего и возникает такая путаница. на скорую руку запатчил, в понедельник отрапортуюсь троллям. надеюсь, расценят как багу, а не как фьюче реквист!
но настроение всё-таки испортили...зелёные какаши

если кому интересно, после ответа троллей выложу патч (а нет - так не выложу :) )


Название: Re: [4.3.3] QSortFilterProxyModel, filterAcceptsColumn, QTableView и сортировка
Отправлено: Alex03 от Декабрь 23, 2007, 15:56
сортировку по столбцу исходной модели тоже полезно оставить, только вот в какомнить методе отличном от sort(), типа sortBySourceColumn(), чтобы вьюхи работали правильно.


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: DS_tm от Июль 24, 2008, 12:37
Ребят, ну что там с этим багом? У меня та же ситуёвина, нужно скрыть ненужные стобцы у модели, и при этом нужна возможность сортировки и по столбцам исходной модели и по столбцам proxy.


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: ритт от Июль 24, 2008, 13:28
а ничего. отрапортовал, таска долгое время была непубличной. потом попросил - её сделали публичной, но там ни статуса, ни шедуля не было. а сейчас и вовсе таску найти не могу (жаль, ид не помню; если кто наткнётся, буду признателен, если запостят ид сюда)

патч (свой), которым пользовался первое время, исправлял ситуёвину с сортировкой, но проявлял какую-то новую проблему (сейчас уже не помню)
т.к. политика троллтека не позволяет фиксить такие баги в патч-релизах, в лучшем случае пофиксят в 4.5.0; оптимум - в 5.0.0; в худшем случае вообще забудут про это или потеряют...

а пока это не вылечат, приходится пользоваться следующей конструкцией:
_исходная_модель_ -> _QSortFilterProxyModel_с_перегруженными_методами_фильтрации_ -> QSortFilterProxyModel
две прокси - это медленнее, чем одна, и это заметно на "больших" моделях, но частично компенсирую потери именно такой последовательностью связки моделей (сначала фильтруем, потом сортируем)


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: DS_tm от Июль 24, 2008, 14:18
да, мне тоже пришло в голову использовать 2 прокси ну со стороны каряво выглядит. А если использовать вьюху, которая просто не будет отображать нужные (ненужные) столбцы? (setColumnHidden)
Еще бы хотелось реализовать возможность пользователю задавать последовательность столбцов в таблице самому. Но тут тож 2 решения, либо писать модль прокси котрая переварачивает все либо реализовывать QTableView с такой возможностью, хотя второе я себе слабо предсталаю.


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: ритт от Июль 24, 2008, 14:57
> А если использовать вьюху, которая просто не будет отображать нужные (ненужные) столбцы? (setColumnHidden)
а если тебе захочется кнопочку "отобразить все столбцы" и/или какой-то контрол для выбора видимых/невидимых столбцов?

> либо писать модль прокси котрая переварачивает все либо реализовывать QTableView с такой возможностью, хотя второе я себе слабо предсталаю.
QHeaderView::saveState(...)/QHeaderView::restoreState(...)


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: DS_tm от Июль 24, 2008, 15:19
> а если тебе захочется кнопочку "отобразить все столбцы" и/или какой-то контрол для выбора видимых/невидимых столбцов?
Мне, собственно, это и нужно ;). А что мешает создать такой кантрол, в котором будут хронится индексы отоброжаемыx\неотоброжаемых элементов. В дальнейшем пробкгать по столбцам таблицы и вызывать setColumnHidden(index, false) - для видимых и setColumnHidden(index, true) для невидимых?

А кнопочку "отобразить все столбцы" можно реализовать также, к примеру создать функцию у наследника от QTableView showAllColumns(), которая пробегает по всем стобцам и использует showColumn(index)


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: EhTemka от Июль 24, 2008, 15:27
Цитировать
> а если тебе захочется кнопочку "отобразить все столбцы" и/или какой-то контрол для выбора видимых/невидимых столбцов?
Мне, собственно, это и нужно Wink. А что мешает создать такой кантрол, в котором будут хронится индексы отоброжаемыx\неотоброжаемых элементов. В дальнейшем пробкгать по столбцам таблицы и вызывать setColumnHidden(index, false) - для видимых и setColumnHidden(index, true) для невидимых?

А кнопочку "отобразить все столбцы" можно реализовать также, к примеру создать функцию у наследника от QTableView showAllColumns(), которая пробегает по всем стобцам и использует showColumn(index)

Можно проще, через наследника QHeaderView. Колонки можно скрывать и показывать через контекстное меню хедера. Я как то такое реализовывал (ну если чесно реализовывал не я. Я всего лишь адаптировал под свои нужды). Если интересно могу выложить. ТАм кстати есть возможность сохранения/восстановления текущего состояния.


Название: Re: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка
Отправлено: ритт от Июль 24, 2008, 15:31
для этих целей есть прокси-модели - и не нужно городить велосипед

такой контрол у меня уже есть готовый. работает с любым хидервью. + есть наследник хидервью с контекстным меню и тултипами.
могу поделиться взамен на что-нибудь полезное )