是否可以使用 setSortRole() 在 QSortFilterProxyModel 中按 bool 设置顺序?
Is possible set order by bool in QSortFilterProxyModel with setSortRole()?
你好,我有一个 class Filtro(英文是 Filter),它是 QSortFilterProxyModel ,我已经用 myModel class 设置了她的 sourceModel。 myModel class 是这个 class 中的一个 QAbstractListModel 我有一个
QList<Tile> m_recipes;
方块class是这样的:
class Tile {
public :
Tile (const QString &nameRecipe,const QString &color,const int &duration,const bool &userRecipe);
QString nameRecipe()const;
QString color() const;
int duration() const;
bool userRecipe() const;
private:
QString m_nameRecipe;
QString m_color;
int m_duration;
bool m_UserRecipe;
};
现在,当我使用 class Filtro 过滤列表时,我想在 qml 中显示所有带有 m_UserRecipe == true 的元素之前以及所有带有 m_UserRecipe 的元素之后== 错误。
所以我的问题是:在 QSortFilterProxyModel 中,可以设置一个具有 rapresents 布尔值的角色的顺序?
QHash<int, QByteArray> myModel::roleNames() const
{
QHash <int,QByteArray> roles;
roles[NameRecipe]="NameRecipe";
roles[Color]="Color";
roles[Duration]="Duration";
roles[UserRecipe]="userRecipe";
return roles;
}
filtro.h :
class Filtro : public QSortFilterProxyModel
{
Q_OBJECT
public:
Filtro(QObject* parent=0);
~Filtro();
Q_INVOKABLE void setStringaFiltro(QString string);
Q_PROPERTY(bool showOnlyUserRic READ showOnlyUserRic WRITE setshowOnlyUserRic NOTIFY showOnlyUserRicChanged)
Q_PROPERTY(QString string READ string WRITE setstring NOTIFY stringChanged)
public slots:
void setshowOnlyUserRic(bool showOnlyUserRic);
bool showOnlyUserRic() const;
QString string() const;
void setstring(QString string);
signals:
void showOnlyUserRicChanged();
void oggettiFiltChanged();
void stringChanged();
private:
bool m_showOnlyUserRic;
int m_oggettiFilt;
QString m_string;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
};
filtro.cpp
Filtro::Filtro(QObject *parent): QSortFilterProxyModel(parent)
, m_showOnlyUserRic(false)
,m_oggettiFilt(0)
,m_string("")
{
this->setSourceModel(&myModel);
}
Filtro::~Filtro()
{
}
void Filtro::setStringaFiltro(QString string)
{
this->setFilterCaseSensitivity(Qt::CaseInsensitive); // lo rendo case insensitive
this->setFilterFixedString(string);
}
QString Filtro::string() const
{
return m_string;
}
void Filtro::setstring(QString string)
{
if (m_string == string)
return;
m_string = string;
emit stringChanged();
invalidateFilter(); // fa rivalutare il filtro e quindi entra di nuovo in filterAcceptsRows()
}
bool Filtro::showOnlyUserRic() const
{
return m_showOnlyUserRic;
}
void Filtro::setshowOnlyUserRic(bool showOnlyUserRic)
{
if (m_showOnlyUserRic == showOnlyUserRic)
return;
m_showOnlyUserRic = showOnlyUserRic;
emit showOnlyUserRicChanged();
invalidateFilter(); // fa rivalutare il filtro e quindi entra di nuovo in filterAcceptsRows()
}
bool Filtro::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QRegExp regEx("*"+string()+"*");
regEx.setPatternSyntax(QRegExp::Wildcard);
regEx.setCaseSensitivity(Qt::CaseInsensitive);
if(showOnlyUserRic()==true) {
// se devo visualizzare solo
QModelIndex ricUtente = sourceModel()->index(source_row,0, source_parent); // vado a leggere singolarmente ogni riga del modello
QString stringaConfronto=sourceModel()->data(ricUtente,modello::NomeRicetta).toString();
if(sourceModel()->data(ricUtente,modello::RicettaUtente)==true && stringaConfronto.contains(regEx)==true)
{
// se è ricetta utente
return true;
}
else{
return false;
}
}
else{
QModelIndex ricUtente = sourceModel()->index(source_row,0, source_parent); // vado a leggere singolarmente ogni riga del modello
QString stringaConfronto=sourceModel()->data(ricUtente,modello::NomeRicetta).toString();
if(stringaConfronto.contains(regEx))
return true;
// if(sourceModel()->data(ricUtente,modello::NomeRicetta)== string() ) //confronto il roles ricetta utene x filtrare il
// {
// return true;
// }
return false;
}
}
如果您想要那种类型的订单,您只需覆盖 lessThan
方法:
bool Filtro::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
bool leftData = sourceModel()->data(left, modello::UserRecipe).toBool();
bool rightData = sourceModel()->data(right, modello::UserRecipe).toBool();
if(leftData != rightData){
return leftData;
}
else
return QSortFilterProxyModel::lessThan(left, right);
}
更新:
你必须调用 sort(0)
(这个数字无关紧要,因为它是为 multi-column 模型制作的,但在你的情况下它不是。),同时启用 dynamicSortFilter
,对于你的最后一个,你必须将排序角色设置为 modello::NomeRicetta
:
Filtro::Filtro(QObject *parent): QSortFilterProxyModel(parent)
, m_showOnlyUserRic(false)
,m_oggettiFilt(0)
,m_string("")
{
setFilterRole(modello::RicettaUtente);
setSortRole(modello::NomeRicetta);
setDynamicSortFilter(true);
sort(0);
}
完整的例子可以在这里找到 link
你好,我有一个 class Filtro(英文是 Filter),它是 QSortFilterProxyModel ,我已经用 myModel class 设置了她的 sourceModel。 myModel class 是这个 class 中的一个 QAbstractListModel 我有一个
QList<Tile> m_recipes;
方块class是这样的:
class Tile {
public :
Tile (const QString &nameRecipe,const QString &color,const int &duration,const bool &userRecipe);
QString nameRecipe()const;
QString color() const;
int duration() const;
bool userRecipe() const;
private:
QString m_nameRecipe;
QString m_color;
int m_duration;
bool m_UserRecipe;
};
现在,当我使用 class Filtro 过滤列表时,我想在 qml 中显示所有带有 m_UserRecipe == true 的元素之前以及所有带有 m_UserRecipe 的元素之后== 错误。 所以我的问题是:在 QSortFilterProxyModel 中,可以设置一个具有 rapresents 布尔值的角色的顺序?
QHash<int, QByteArray> myModel::roleNames() const
{
QHash <int,QByteArray> roles;
roles[NameRecipe]="NameRecipe";
roles[Color]="Color";
roles[Duration]="Duration";
roles[UserRecipe]="userRecipe";
return roles;
}
filtro.h :
class Filtro : public QSortFilterProxyModel
{
Q_OBJECT
public:
Filtro(QObject* parent=0);
~Filtro();
Q_INVOKABLE void setStringaFiltro(QString string);
Q_PROPERTY(bool showOnlyUserRic READ showOnlyUserRic WRITE setshowOnlyUserRic NOTIFY showOnlyUserRicChanged)
Q_PROPERTY(QString string READ string WRITE setstring NOTIFY stringChanged)
public slots:
void setshowOnlyUserRic(bool showOnlyUserRic);
bool showOnlyUserRic() const;
QString string() const;
void setstring(QString string);
signals:
void showOnlyUserRicChanged();
void oggettiFiltChanged();
void stringChanged();
private:
bool m_showOnlyUserRic;
int m_oggettiFilt;
QString m_string;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
};
filtro.cpp
Filtro::Filtro(QObject *parent): QSortFilterProxyModel(parent)
, m_showOnlyUserRic(false)
,m_oggettiFilt(0)
,m_string("")
{
this->setSourceModel(&myModel);
}
Filtro::~Filtro()
{
}
void Filtro::setStringaFiltro(QString string)
{
this->setFilterCaseSensitivity(Qt::CaseInsensitive); // lo rendo case insensitive
this->setFilterFixedString(string);
}
QString Filtro::string() const
{
return m_string;
}
void Filtro::setstring(QString string)
{
if (m_string == string)
return;
m_string = string;
emit stringChanged();
invalidateFilter(); // fa rivalutare il filtro e quindi entra di nuovo in filterAcceptsRows()
}
bool Filtro::showOnlyUserRic() const
{
return m_showOnlyUserRic;
}
void Filtro::setshowOnlyUserRic(bool showOnlyUserRic)
{
if (m_showOnlyUserRic == showOnlyUserRic)
return;
m_showOnlyUserRic = showOnlyUserRic;
emit showOnlyUserRicChanged();
invalidateFilter(); // fa rivalutare il filtro e quindi entra di nuovo in filterAcceptsRows()
}
bool Filtro::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QRegExp regEx("*"+string()+"*");
regEx.setPatternSyntax(QRegExp::Wildcard);
regEx.setCaseSensitivity(Qt::CaseInsensitive);
if(showOnlyUserRic()==true) {
// se devo visualizzare solo
QModelIndex ricUtente = sourceModel()->index(source_row,0, source_parent); // vado a leggere singolarmente ogni riga del modello
QString stringaConfronto=sourceModel()->data(ricUtente,modello::NomeRicetta).toString();
if(sourceModel()->data(ricUtente,modello::RicettaUtente)==true && stringaConfronto.contains(regEx)==true)
{
// se è ricetta utente
return true;
}
else{
return false;
}
}
else{
QModelIndex ricUtente = sourceModel()->index(source_row,0, source_parent); // vado a leggere singolarmente ogni riga del modello
QString stringaConfronto=sourceModel()->data(ricUtente,modello::NomeRicetta).toString();
if(stringaConfronto.contains(regEx))
return true;
// if(sourceModel()->data(ricUtente,modello::NomeRicetta)== string() ) //confronto il roles ricetta utene x filtrare il
// {
// return true;
// }
return false;
}
}
如果您想要那种类型的订单,您只需覆盖 lessThan
方法:
bool Filtro::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
bool leftData = sourceModel()->data(left, modello::UserRecipe).toBool();
bool rightData = sourceModel()->data(right, modello::UserRecipe).toBool();
if(leftData != rightData){
return leftData;
}
else
return QSortFilterProxyModel::lessThan(left, right);
}
更新:
你必须调用 sort(0)
(这个数字无关紧要,因为它是为 multi-column 模型制作的,但在你的情况下它不是。),同时启用 dynamicSortFilter
,对于你的最后一个,你必须将排序角色设置为 modello::NomeRicetta
:
Filtro::Filtro(QObject *parent): QSortFilterProxyModel(parent)
, m_showOnlyUserRic(false)
,m_oggettiFilt(0)
,m_string("")
{
setFilterRole(modello::RicettaUtente);
setSortRole(modello::NomeRicetta);
setDynamicSortFilter(true);
sort(0);
}
完整的例子可以在这里找到 link