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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QSortFilterProxyModel - фильтр по списку  (Прочитано 12182 раз)
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« : Апрель 20, 2015, 21:18 »

Для QFileSystemModel есть метод setNameFilters для фильтрации по списку.
Подскажите пожалуйста как организовать подобное для QSortFilterProxyModel + QListView?
« Последнее редактирование: Апрель 20, 2015, 21:21 от Serega » Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #1 : Апрель 21, 2015, 05:15 »

Решил вопрос переопределением метода filterAcceptsRow:
Код
C++ (Qt)
bool ProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
 QStringList filterList;
 filterList << "expression1" << "expression2"<< "expression3";
 return filterList.contains(sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).toString());
}
Есть ли еще более оптимальные решения?
« Последнее редактирование: Апрель 21, 2015, 05:41 от Serega » Записан
ksk-
Самовар
**
Offline Offline

Сообщений: 178



Просмотр профиля
« Ответ #2 : Апрель 21, 2015, 07:09 »

Решил вопрос переопределением метода filterAcceptsRow:

Насколько я помню, это именно так и делается.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #3 : Апрель 21, 2015, 09:48 »

несколько замечаний
по первых вместо списка лучше использовать QSet<QString>, который намного быстрее выполняет contains(). Проверено на личном опыте, в разы быстрее.
Из QListWidget можно получить методом QSet::fromList<QString>(list).
и сделать ваш qset члентом класса для более быстрого доступа (хотя может вы просто код упростили).
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #4 : Апрель 21, 2015, 10:01 »

Спасибо! Мне как раз как воздух необходимы советы по оптимизации кода. Личная практика очень мала, а кодидь хочется сразу правильно.
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #5 : Апрель 21, 2015, 11:11 »

По поводу второго совета.
В ригинале QStringListModel + QListView - хранит поступающие данные. Необходимо организовать различную фильтрацию. Использую QSortFilterProxyModel.
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #6 : Апрель 22, 2015, 09:04 »

Если добавляю в Model (QListView) новое слово, то в ProxyModel изменения происходят параллельно.
При добавлении нового слова в фильтрующий список QSet или при его смене, изменей в ProxyModel нет пока не дабавлю новое слово в основную модель.
Как поправить?
« Последнее редактирование: Апрель 22, 2015, 09:25 от Serega » Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #7 : Апрель 22, 2015, 09:30 »

После смены фильтрующего списка QSet, вызвал метод invalidateFilter ();. Вроде как работает.
Подскажите правильно ли я понял этот метод?
Код
C++ (Qt)
void ProxyModel::openFilterFile( QString const & name )
{
 m_filterSet.clear();
 
 QFile file(name);
 if (file.open(QIODevice::ReadOnly)) {
   QTextStream stream(&file);
   while (!stream.atEnd()) {
     QString line = stream.readLine();
     m_filterSet.insert(line);
   }
 }
 
 invalidateFilter ();
}
« Последнее редактирование: Апрель 22, 2015, 09:35 от Serega » Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #8 : Апрель 23, 2015, 09:22 »

если работет, то правильно  Улыбающийся
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #9 : Апрель 23, 2015, 10:10 »

Работает та без проблем. Но может этот метод просто выдает какой сигнал, который обновляет представление, а сам предназначен для чего то иного. Честно не осознал для чего. Работает, но не хотелось бы что бы что то работало в холостую. Хотелось бы использовать именно то, что для этого и предназначено.
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #10 : Апрель 24, 2015, 09:36 »

Основной список несортирован.
При установке прокси список так же не сортирован.
Создаю меню - Сортровать по алфавиту. Здесь все в порядке.

Создаю меню - Отменить сортировку. Как вернуть в исходное состояние Проксимодель? Метод invalidate() не помогает.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #11 : Апрель 24, 2015, 09:47 »

Исходное состояние у вас есть в QStringListModel
Записан

Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #12 : Апрель 24, 2015, 10:13 »

К сожалению не осознал.
Для прокси свое окно. И повторная установка оригинальной модели не дает результат:
m_proxyModel->setSourceModel(m_sourseModel);
m_proxyList->setModel(m_proxyModel);


Даже если перед этим поставть метод invalidate();
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #13 : Апрель 24, 2015, 12:09 »

Сбрость m_proxyModel не удается.
Создал слот:
Код
C++ (Qt)
void proxyPaneWidget::noSortProxy()
{
 m_proxyModel = new ProxyModel( this );
 m_proxyModel ->setSourceModel( m_sourseModel );
 m_proxyList->setModel( m_proxyModel );
}

Однако изначально m_proxyModel инициализируется в конструкторе, таким же образом: m_proxyModel = new ProxyModel( this );.
Насколько корректно такое решение и какими неприятностями оно может грозить? Может ли привести к утечке памяти? И может все таки можно как то сбросить исходную модель? Метод reset() не помогает и invalidate() вроде как отвечает за сброс сортировки, так же почему то не срабатывает. Какие могут быть ошибки?
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #14 : Апрель 26, 2015, 14:34 »

Еще заморочка. Комбинирую фильтр с RegExp. Ловлю QString со строки ввода. И тут все в порядке:
Код
C++ (Qt)
bool proxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
 QString word = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).toString();
 
 if(m_filterSet.contains(word))
 {
   QRegExp rx(filterRegExp().pattern(), Qt::CaseInsensitive, QRegExp::WildcardUnix);
 
   emit proxyDataChanged(); //HOW TO DO
 
   return word.contains(rx);
 }
 return false;
}

Но необходимо обновить счетчик пойманных слов в другом объекте. Отправляю сигнал emit proxyDataChanged();. Однако с этого переопределенного слота сигнал не отправляется. Как быть?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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