Сортировка и фильтрация в QTableView, связь с моделью через Custom QSortFilterProxyModel
QTableView, QSortFilterProxyModel
Имеется QSqlQueryModel, делаю proxyModel->setSourceModel(model) и view->setModel(proxyModel).
view->setSortingEnabled(true) работает отлично, но пытаюсь по клику на строчку получить данные и понимаю что сортируется только view, а в модели сортировка не меняется.
То есть если была таблица с данными по возрастанию row1, row2, row3; я отсортировал row3, row2, row1 - по клику на row3 получаю доступ к row1.
Если у кого-то есть понимание поделитесь пожалуйста.
upd: помогли подсказки и поддержка пользователей и этот найденный пример.
custom_sort_filter_proxy_model.h
#include <QApplication> #include <QtWidgets> class NameYearFilterProxyModel : public QSortFilterProxyModel{ Q_OBJECT QRegExp nameRegExp; QRegExp yearRegExp; public: explicit NameYearFilterProxyModel(QObject* parent= nullptr): QSortFilterProxyModel(parent) { nameRegExp.setCaseSensitivity(Qt::CaseInsensitive); yearRegExp.setCaseSensitivity(Qt::CaseInsensitive); yearRegExp.setPatternSyntax(QRegExp::RegExp); nameRegExp.setPatternSyntax(QRegExp::RegExp); } bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override{ QModelIndex nameIndex= sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex yearIndex= sourceModel()->index(sourceRow, 1, sourceParent); QString name= sourceModel()->data(nameIndex).toString(); QString year= sourceModel()->data(yearIndex).toString(); return ( name.contains(nameRegExp) && year.contains(yearRegExp) ); } public slots: void setNameFilter(const QString& regExp){ nameRegExp.setPattern(regExp); invalidateFilter(); } void setYearFilter(const QString& regExp){ yearRegExp.setPattern(regExp); invalidateFilter(); } };
custom_sort_filter_proxy_model.cpp
#include "custom_sort_filter_proxy_model.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); //set up GUI QWidget w; w.setWindowTitle("Custom SortFilterProxyModel"); QVBoxLayout layout(&w); QHBoxLayout hLayout; QLineEdit lineEditName; QLineEdit lineEditYear; lineEditName.setPlaceholderText("name filter"); lineEditYear.setPlaceholderText("year filter"); lineEditYear.setValidator(new QRegExpValidator(QRegExp("[0-9]*"))); lineEditYear.setMaxLength(4); hLayout.addWidget(&lineEditName); hLayout.addWidget(&lineEditYear); QTableView tableView; layout.addLayout(&hLayout); layout.addWidget(&tableView); //set up models QStandardItemModel sourceModel; NameYearFilterProxyModel filterModel;; filterModel.setSourceModel(&sourceModel); tableView.setModel(&filterModel); QObject::connect(&lineEditName, &QLineEdit::textChanged, &filterModel, &NameYearFilterProxyModel::setNameFilter); QObject::connect(&lineEditYear, &QLineEdit::textChanged, &filterModel, &NameYearFilterProxyModel::setYearFilter); QVector<QString> names{"Danny", "Christine", "Lars", "Roberto", "Maria"}; for(int i=0; i<100; i++){ QList<QStandardItem*> row; row.append(new QStandardItem(names[i%names.size()])); row.append(new QStandardItem(QString::number((i%9)+1980))); sourceModel.appendRow(row); } w.show(); return a.exec(); }
Так же решение со сбитой нумерацией строк в комментариях.
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.Вам це подобається? Поділіться в соціальних мережах!
- Akiv Doros
- 11 листопада 2024 р. 14:58
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:50бали,
- Рейтинг балів-4
- molni99
- 26 жовтня 2024 р. 01:37
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:80бали,
- Рейтинг балів4
- molni99
- 26 жовтня 2024 р. 01:29
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:20бали,
- Рейтинг балів-10
А как получаете данные? Код приведите.
Возможно даже лишнего немного оставил, в целом картина такая:
По клику на одну из колонок
Я прошу прощения если от кода глаза слезятся, я учусь.
Без кода сложно сказать.
Лучше всего создать к примеру свои классы
В этих классах переопределить виртуальные методы ... взависимости от кода и проекта.
код я тут привёл https://evileg.com/en/forum/topic/1421/#post-8028
Страшно даже думать об этом, но если нет стандартных решений то придётся учиться.
Спасибо за ответ!
Выложети весь код.
Не понятно proxyOneModel ...
С вашего кода я понимаю (годаю) что proxyOneModel унаследован от QSqlQueryModel
Вы должны использовать класс QSortFilterProxyModel
Сортировка должна происходить в proxy , получать данные из model
Пытался адаптировать, чтобы не вникать в подробности, типа правила хорошего тона. Позже выложу по максимуму тогда. p.s., да, proxy это QSortFilterProxyModel
весь код как есть добавил в тело поста
Так. Убрал позорятину свою и без неё теперь видно. Заметил ошибку
тут model заменил на proxy:
всё заработало как надо!
спасибо всем кто отреагировал!!!
Да, не успел указать.
Спасибо! :) Фух, достала эта ошибка.
А что по решаемой задаче должно получаться? У меня такое чувство, что вы лишних моделей QSortFilterProxy понасоздавали и всё можно было в одну модель засунуть.
Может быть и лишние, но не понял как по-другому. Каждая модель для отдельного фильтра
ведь можно установить только один FilterKeyColumn для модели:
Посмотрите в сторону кастомной модели от QSortFilterProxyModel. В примерах Qt есть, Custom Sort/Filter Model Example. Так можно реализовать фильтрацию по нескольким полям, как вам и надо.
Попробую и тогда отпишусь по результату.
По поводу вашего когда.
1 - Согласен с МаркГлен ...
2 - Когда вы определяете/устанавливаете ширину колонок лучше использовать локальные константы (код лучше читается).
Пример:
3 - По поводу connect используете старый синтаксис.
Забегая наперед - у вас возникла ещё одна проблема с сортировкой нумерации строк.
Как уже было сказано ...
Необходимо переопределить виртуальный метод ...
Сложновато для меня, не понимаю что надо делать и что происходит. Наверное мне ещё рано.
Собезъянничал вот так:
basesortfilterproxymodel.h
basesortfilterproxymodel.cpp
Заменил везде QSortFilterProxyModel на BaseSortFilterProxyModel, ничего не меняется. Наверное если сходу не понятно, то бесполезно и пытаться разобраться? Или есть какие-то доки и мануалы которые можно почитать.
Пример смотрели? Там всё более-менее понятно.
Ну с сортировкой вертикальных заголовков разобрался теперь :)
Фильтры смотрю.
Доброго времени суток.
Вы начали правильно, но должны продолжить и дочитать документацию до конца.
Вам нужно разобраться с методом bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
Лучше всего создать проект-пример в котором запустить отладку проекта и разобраться.
1. Документация
2. Путь к примеру из самого QT Creator (у меня linux) - Qt/Examples/Qt-5.14.2/widgets/itemviews/customsortfiltermodel
Не сдавайтесь и будьте упрямее ...
... перечитайте ещё раз, если не поймёте запустите отладку проекта-примера и разберитесь в простом примере, а уж потом подумайте как применить к вашему проекту.
Итого, пришёл с одной проблемой, обнаружилось ещё несколько. Все были решены :) Но это я ещё остальной код не показывал. Понимаю что не хватает пару лет поработать джуном где-нибудь. Надо будет вам дать отревьюить как закончу.
Сделал изменения в теле топика.
Теперь ещё надо все миллион сигналов переписать по-новому.