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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [4.3.*][бага] QSortFilterProxyModel, filterAcceptsColumn, QTableView, сортировка  (Прочитано 12556 раз)
ритт
Гость
« : Декабрь 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);

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

прокся, хоть и попрятала столбцы по щучьему велению, а нормально маппиться не хочет, собака. и сижу мозг ломаю как ей доказать, что не по тому столбцу сортирует!
возможно, я в изобретатели велосипедов подался, но, вроде, прокся для того и нужна, чтобы что-то прятать и переворачивать
« Последнее редактирование: Декабрь 23, 2007, 12:26 от xep » Записан
Alex03
Гость
« Ответ #1 : Декабрь 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)

легко мог ошибиться гденить.
Записан
ритт
Гость
« Ответ #2 : Декабрь 23, 2007, 12:24 »

спасибо за ответ

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

если кому интересно, после ответа троллей выложу патч (а нет - так не выложу Улыбающийся )
Записан
Alex03
Гость
« Ответ #3 : Декабрь 23, 2007, 15:56 »

сортировку по столбцу исходной модели тоже полезно оставить, только вот в какомнить методе отличном от sort(), типа sortBySourceColumn(), чтобы вьюхи работали правильно.
Записан
DS_tm
Гость
« Ответ #4 : Июль 24, 2008, 12:37 »

Ребят, ну что там с этим багом? У меня та же ситуёвина, нужно скрыть ненужные стобцы у модели, и при этом нужна возможность сортировки и по столбцам исходной модели и по столбцам proxy.
Записан
ритт
Гость
« Ответ #5 : Июль 24, 2008, 13:28 »

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

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

а пока это не вылечат, приходится пользоваться следующей конструкцией:
_исходная_модель_ -> _QSortFilterProxyModel_с_перегруженными_методами_фильтрации_ -> QSortFilterProxyModel
две прокси - это медленнее, чем одна, и это заметно на "больших" моделях, но частично компенсирую потери именно такой последовательностью связки моделей (сначала фильтруем, потом сортируем)
Записан
DS_tm
Гость
« Ответ #6 : Июль 24, 2008, 14:18 »

да, мне тоже пришло в голову использовать 2 прокси ну со стороны каряво выглядит. А если использовать вьюху, которая просто не будет отображать нужные (ненужные) столбцы? (setColumnHidden)
Еще бы хотелось реализовать возможность пользователю задавать последовательность столбцов в таблице самому. Но тут тож 2 решения, либо писать модль прокси котрая переварачивает все либо реализовывать QTableView с такой возможностью, хотя второе я себе слабо предсталаю.
« Последнее редактирование: Июль 24, 2008, 14:24 от DS_tm » Записан
ритт
Гость
« Ответ #7 : Июль 24, 2008, 14:57 »

> А если использовать вьюху, которая просто не будет отображать нужные (ненужные) столбцы? (setColumnHidden)
а если тебе захочется кнопочку "отобразить все столбцы" и/или какой-то контрол для выбора видимых/невидимых столбцов?

> либо писать модль прокси котрая переварачивает все либо реализовывать QTableView с такой возможностью, хотя второе я себе слабо предсталаю.
QHeaderView::saveState(...)/QHeaderView::restoreState(...)
Записан
DS_tm
Гость
« Ответ #8 : Июль 24, 2008, 15:19 »

> а если тебе захочется кнопочку "отобразить все столбцы" и/или какой-то контрол для выбора видимых/невидимых столбцов?
Мне, собственно, это и нужно Подмигивающий. А что мешает создать такой кантрол, в котором будут хронится индексы отоброжаемыx\неотоброжаемых элементов. В дальнейшем пробкгать по столбцам таблицы и вызывать setColumnHidden(index, false) - для видимых и setColumnHidden(index, true) для невидимых?

А кнопочку "отобразить все столбцы" можно реализовать также, к примеру создать функцию у наследника от QTableView showAllColumns(), которая пробегает по всем стобцам и использует showColumn(index)
Записан
EhTemka
Гость
« Ответ #9 : Июль 24, 2008, 15:27 »

Цитировать
> а если тебе захочется кнопочку "отобразить все столбцы" и/или какой-то контрол для выбора видимых/невидимых столбцов?
Мне, собственно, это и нужно Wink. А что мешает создать такой кантрол, в котором будут хронится индексы отоброжаемыx\неотоброжаемых элементов. В дальнейшем пробкгать по столбцам таблицы и вызывать setColumnHidden(index, false) - для видимых и setColumnHidden(index, true) для невидимых?

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

Можно проще, через наследника QHeaderView. Колонки можно скрывать и показывать через контекстное меню хедера. Я как то такое реализовывал (ну если чесно реализовывал не я. Я всего лишь адаптировал под свои нужды). Если интересно могу выложить. ТАм кстати есть возможность сохранения/восстановления текущего состояния.
Записан
ритт
Гость
« Ответ #10 : Июль 24, 2008, 15:31 »

для этих целей есть прокси-модели - и не нужно городить велосипед

такой контрол у меня уже есть готовый. работает с любым хидервью. + есть наследник хидервью с контекстным меню и тултипами.
могу поделиться взамен на что-нибудь полезное )
« Последнее редактирование: Июль 24, 2008, 15:50 от Константин » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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