c++ - 是否可以使用 setSortRole() 在 QSortFilterProxyModel 中按 bool 设置顺序?

标签 c++ qt qml qsortfilterproxymodel qabstractlistmodel

你好,我有一个 Filtro 类(英文是 Filter),它是 QSortFilterProxyModel ,我已经用 myModel 类设置了她的 sourceModel 。 myModel 类是此类中的 QAbstractListModel 我有一个

QList<Tile> m_recipes; 

Tile 类是这样的:

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;
};

现在,当我使用 Filtro 类过滤列表时,我想在 qml 中显示所有具有 m_UserRecipe == true 的元素之前和所有具有 m_UserRecipe == false 的元素之后。 所以我的问题是:在 QSortFilterProxyModel 中,可以设置一个具有 rapresents bool 值的角色的顺序?

QHash<int, QByteArray> myModel::roleNames() const
{

    QHash <int,QByteArray> roles;
    roles[NameRecipe]="NameRecipe";
    roles[Color]="Color";
    roles[Duration]="Duration";
    roles[UserRecipe]="userRecipe";
    return roles;

}

过滤器.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;

};

过滤.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)(数字无关紧要,因为它是为多列模型制作的,但在您的情况下不是。),同时启用 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 上找到

关于c++ - 是否可以使用 setSortRole() 在 QSortFilterProxyModel 中按 bool 设置顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48842998/

相关文章:

c++ - boost 库中的超图支持

html - 文本对齐在 QTextDocument 的 setHTML 中不起作用?

c++ - 为什么我从我的 QTouchPoint 获得无效数据?

javascript - 将 Node JS 库与 QML 一起使用

c++ - 如何读取控制台输入并将其存储到 vector 字符串中

c++ - 如何将 C/C++ 库代码封装为可在具有多个实例的单独线程中运行?

qt - 如何在图像中设置渐变不透明度?

c++ - QT/QML c++ 程序在从 QML 访问 QList 时崩溃

c++ - unique_ptr、make_unique 和多态性

java - 使用 JNI 将字符串从 Java 传递到 C++