Russian Qt Forum

Qt => Вопросы новичков => Тема начата: helga1917 от Август 12, 2013, 13:12



Название: фильтрация по иконкам
Отправлено: helga1917 от Август 12, 2013, 13:12
У меня есть таблица QSortFilterProxyModel в одной из колонок таблицы иконки (в формате png) обозначающие тип сообщений. Как можно сделать фильтрацию по определенному типу иконок?


Название: Re: фильтрация по иконкам
Отправлено: kambala от Август 12, 2013, 13:25
введи какой-нибудь строковый идентификатор, например имя файла


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 12, 2013, 13:54
не происходит фильтрация
Код:
Window::Window
{
proxyModel = new QSortFilterProxyModel (this);

filterButton = new QPushButton;
connect (filterButton, SIGNAL(clicked()), this, SLOT(setFilterType()));
}
void Window::setFiltertype()
{
proxyModel->setFilterRole(1);
QRegExp regExp("C:/1.png");
proxyModel->setFilterRegExp(regExp);
}



Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 12, 2013, 15:51
а что у тебя возвращается по первой роли?
Кстати, а модель фильтру ты указала?


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 12, 2013, 16:19
Иконка со строкой просто не сравнивается. Заведи отдельную роль с типом записи и по ней фильтруй


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 16, 2013, 14:07
Цитировать
а что у тебя возвращается по первой роли?
proxyModel->setFilterRole(Qt::DecorationRole);

Цитировать
Кстати, а модель фильтру ты указала?
Заведи отдельную роль с типом записи и по ней фильтруй
Не понимаю, что это значит?
Как указать модель фильтру? Как завести роль с типом записи?


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 16, 2013, 14:17
Ок, какой тип у тебя возвращается по роли Qt::DecorationRole? QImage?

proxyModel->setModel() делала?

В data() методе модели по запросу какой-нить своей роли возвращай тип записи.
proxyModel->setFilterRole(<тут укажешь свою роль>);


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 16, 2013, 14:44
Возвратить надо QPixmap.
Цитировать
proxyModel->setModel() делала?
да, это есть
Цитировать
В data() методе модели по запросу какой-нить своей роли возвращай тип записи.
Тут немного не понятно: возвращает тип записи или данные?


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 16, 2013, 14:51
QPixmap с QString не сравнивается, поэтому и не получится фильтрации

Данные, которые бы обозначали тип записи. Например enum или просто int, по которому можно отфильтровать


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 20, 2013, 10:18
А как правильно реализовать саму фильтрацию по идентификатору?
если, допустим, создать идентификатор QString  id
main:
Код:
void addMail(QAbstractItemModel *model, const QString id, const QPixmap Pix,
                  const QDateTime &date, const QString &info)
{model->setData(model->index(0,0),id, 3);              //идентификатор, 3 роль ToolTipRole(если прописать тут 0,
                                                                        // то фильтрует, но тогда id отображается на форме)
model->setData(model->index(0,0),Pix,1);            //иконка
model->setData(model->index(0,1),date);            //время
model->setData(model->index(0,2),info);             //текст сообщения
}
QAbstractItemModel *createMailModel (QObject *parent)
{QStandardItemModel *model2 = new StandardItemModel (0,3, parent);

QPixmap *pixCrash = new QPixmap ("crash.png");
QPixmap *pixAtt = new QPixmap ("att.png");

addMail (model2, "1", *pixCrash, QDateTime(QDate(2013,12,23),QTime(17,03)), QObject::tr("Сообщение"));
addMail (model2, "2", *pixAtt, QDateTime(QDate(2013,12,23),QTime(17,03)), QObject::tr("Сообщение"));
return model2;
}

Код:
void Window::iconFilter()
{
proxyModel-> setFilterRegExp(QRegExp ("1")); //фильтр "не видит" id
}
Как фильтровать по элементам модели, которые не видимы на форме?


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 20, 2013, 10:26
setFilterRole(3)


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 20, 2013, 10:38
прописала так, но не срабатывает
Код:
void Window::iconFilter()
{
proxyModel->setFilterRole(3);
proxyModel-> setFilterRegExp(QRegExp ("1")); //фильтр "не видит" id
}


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 20, 2013, 10:40
что значит "фильтр не видит id"?
Почему у тебя скобки нехватает второй раз уже?


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 20, 2013, 10:43
скобку исправила, это опечатка

когда у меня id по 0 роли, видим на форме фильтр срабатывает,
а когда id по 3 роли, невидим на форме фильтр не срабатывает


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 20, 2013, 10:44
Покажи весь код, связанный с моделью и фильтром. или выложи минимальный пример


Название: Re: фильтрация по иконкам
Отправлено: Majestio от Август 20, 2013, 11:22
helga1917, попробуйте переосмыслить ваш подход к реализации.

Я напомню:
  • представление - позволяет отображать данные
  • модель - позволяет отдавать данные, и не обязательно их хранить в себе, это может быть и другой источник, в зависимости от типа используемой модели
  • делегат - позволяет изменить отображение данных

Таким образом, от модели вам нужно только одно, отдавать числовые и строковые данные. Прорисовкой иконок пусть занимается делегат. Увидит тип сообщения int 1 - одна иконка, int 2 - другая

Остается задача фильтрации по данным (например, по типу сообщения).
Попробуйте bool QSortFilterProxyModel::filterAcceptsRow

... ну а иконки пусть рисует делегат.

И вдогоночку, а если работаете с БД, почему бы фильтрацию не возложить на БД?


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 20, 2013, 11:26
Ну технически сейчас иконки тоже делегат рисует. Дефолтный


Название: Re: фильтрация по иконкам
Отправлено: Majestio от Август 20, 2013, 11:41
Ну технически сейчас иконки тоже делегат рисует. Дефолтный

А откуда он их берет, из модели? Если "да", это же кощунственно?!


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 20, 2013, 11:43
Зависит от задачи. Иконка может быть не декорацией, а именно самими данными. В этом случае нахождение иконки в модели вполне оправдано


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 20, 2013, 11:49
тут могут быть опечатки, т.к. набираю вручную, копировать возможности нет
main:
Код:
#include <QtGui>
#include "typeFilter.h"
void addMail(QAbstractItemModel *model, const QString id, const QPixmap Pix,
                  const QDateTime &date, const QString &info)
{model->setData(model->index(0,0),id, 3);              //идентификатор, 3 роль ToolTipRole(если прописать тут 0,
                                                                        // то фильтрует, но тогда id отображается на форме)
model->setData(model->index(0,0),Pix,1);            //иконка
model->setData(model->index(0,1),date);            //время
model->setData(model->index(0,2),info);             //текст сообщения
}
QAbstractItemModel *createMailModel (QObject *parent)
{QStandardItemModel *model2 = new StandardItemModel (0,3, parent);

QPixmap *pixCrash = new QPixmap ("crash.png");
QPixmap *pixAtt = new QPixmap ("att.png");

addMail (model2, "1", *pixCrash, QDateTime(QDate(2013,12,23),QTime(17,03)), QObject::tr("Сообщение"));
addMail (model2, "2", *pixAtt, QDateTime(QDate(2013,12,23),QTime(17,03)), QObject::tr("Сообщение"));
return model2;
}
int main (int argc, char *argv[])
{
QApplication app(argc,argv);
Window window;
window.setSourceModel (createMailModel (&window));
window.show();
return app.exec();
}

mysortfilterproxymodel.cpp:
Код:
#include <QtGui>
#include "mysortfilterproxymodel.h"

MySortFilterProxyModel::MySortFilterProxyModel (QObject *parent)
                                 :QSortFilterProxyModel (parent)
{
}
bool MySortFilterProxyModel::filterAcceptRow (int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index0=soutceModel()->index(sourceRow, 0, sourceParent);
return (sourceModel()->data(index0).toString.contains(filterRegExp()));
}
typeFilter.cpp:
Код:
#include <QtGui>
#include "mysortfilterproxymodel.h"
#include "typeFilter.h"
Window::Window()
{
proxyModel = new MySortFilterProxyModel(this);
proxyModel->setFilterKeyColumn(0);

readButton = new QPushButton;

 proxyView = new QTreeView;
proxyView->setRootIsDecorated(false);
proxyView->setModel(proxyModel);
proxyView->setSortingEnabled(true);
proxyView->sortByColumn(0, Qt::AscendingOrder);
proxyView->setSelectionBehavior(QAbstractItenView::SelectRows);

connect (readButton, SIGNAL(clicked()), this, SLOT (iconFilter()));

QHBoxLayout *proxyLayout = new QHBoxLayout;
proxyLayout ->addWidget(readButton);
proxyLayout ->addWidget(proxyView);

setLayout(proxyLayout);
}

void Window::setSourceModel (QAbstractItemModel *model)
{
proxyModel->setSourceModel(model);
}

void Window::iconFilter()
{
proxyModel->setFilterRole(3);
proxyModel->setFilterRegExp(QRegExp("1"));
}
mysortfilterproxymodel.h:
Код:
#ifndef RTY
#define RTY
#include <QSortFilterProxyModel>
#include <QDate>

class MySortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
 MySortFilterProxyModel (QObject *parent = 0);
protected:
bool filterAcceptRow (int sourceRow, const QModelIndex &sourceParent) const;
};
#endif

typeFilrter.h
Код:
#ifndef RTY2
#define RTY2
#include <QWidget>
#include <QModelIndex>
class QAbstractItemModel;
class QTreeView;
class QPushButton;
class MySortFilterProxyModel;
 
class Window : public QWidget
{
Q_OBJECT

public:
Window();
void setSourceModel (QAbstractItemModel *model);

private slots:
void iconFilter();

private:
MySortFilterProxyModel *proxyModel;
QTreeView *proxyView;
QPushButton *readButton;
};
#endif


Название: Re: фильтрация по иконкам
Отправлено: Majestio от Август 20, 2013, 11:50
Зависит от задачи. Иконка может быть не декорацией, а именно самими данными. В этом случае нахождение иконки в модели вполне оправдано

И да, и нет) Если идет речь о неких "статических" по времени данных, например, содержимом комбобокса "Настроение". Да конечно! Но, если мы работаем с БД, в которой несколько миллионов записей, а работа идет по низкоскоростным линиям - только и только абстрактная модель и свой кэширующий механизм доступа к данным, которым она пользуется. И никаких данных в модели! Только способ доступа.


Название: Re: фильтрация по иконкам
Отправлено: mutineer от Август 20, 2013, 11:59
Код
C++ (Qt)
bool MySortFilterProxyModel::filterAcceptRow (int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index0=soutceModel()->index(sourceRow, 0, sourceParent);
return (sourceModel()->data(index0).toString.contains(filterRegExp()));
}
 

Тут ты вытаскиваешь данные из модели по роли Qt::DisplayRole и пытаешься найти в них регексп. А должна вытаскивать по той роли, в которой хранятся фильтруемые данные (в случае приведенного кода Qt::ToolTipRole)

Вообще говоря твоя реализация filterAcceptRow не отличается почти от стандартной, переопределять нет смысла


Название: Re: фильтрация по иконкам
Отправлено: helga1917 от Август 20, 2013, 12:56
Спасибо  :) работает