用自定义的QSortFilterProxyModel实现条件过滤,使qtableview中只显示满足条件的行信息

在实际开发中,qtableview是qt客户端页面中最常用的控件之一。运用qtableview的同时,也会存在着先对初始数据进行过滤,然后在qtableview上展示的只有满足条件的那些信息。或者在不同的条件下要展示出不同的满足条件的行信息。
第一种方法,就是我们在将数据设置在qtableview的model之前,将满足条件的信息筛选出来,然后直接填入model.
第二种方法,就是先不对数据进行处理,直接将数据塞入qtableview的model,然后再给qtableview设置一个筛选代理proxymodel(QSortFilterProxyModel)对model中数据进行刷选,然后展示出来的就是能满足条件的model.
1、先看项目目录结构

用自定义的QSortFilterProxyModel实现条件过滤,使qtableview中只显示满足条件的行信息_第1张图片

2、添加数据model文件, studentmodel.h,studentmodel.cpp
studentmodel.h



#include 
class Student
{
public:
    QString name;  //姓名
    int age;       //年龄
    int height;    //身高
    int weight;    //体重
};
Q_DECLARE_METATYPE(Student);

class StudentModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    enum {
        column_name = 0,
        column_age,
        column_height,
        column_weight
    };
    explicit StudentModel(QObject *parent = nullptr);

    void setInfo(QList<Student>& studentList);

    void clear();

    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;

    QModelIndex parent(const QModelIndex &index) const override;

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

private:
    QList<Student> m_studentList;

};
studentmodel.cpp


#include "studentmodel.h"

StudentModel::StudentModel(QObject *parent)
    : QAbstractItemModel{parent}
{

}

void StudentModel::setInfo(QList<Student>& studentList)
{
    m_studentList = studentList;
    beginInsertRows(QModelIndex(), 0, m_studentList.size() -1);
    endInsertRows();
}

void StudentModel::clear()
{
    m_studentList.clear();
    beginResetModel();
    endResetModel();
}

QModelIndex StudentModel::index(int row, int column, const QModelIndex &parent) const
{
    return createIndex(row, column, nullptr);
}

QModelIndex StudentModel::parent(const QModelIndex &index) const
{
    return QModelIndex();
}

int StudentModel::rowCount(const QModelIndex &parent) const
{
    return m_studentList.size();
}

int StudentModel::columnCount(const QModelIndex &parent) const
{
    return 4;
}

QVariant StudentModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical)
    {
        return QVariant();
    }
    if (role == Qt::DisplayRole)
    {
        switch (section)
        {
        case column_name:
            return tr("name");
            break;
        case column_age:
            return tr("age");
            break;
        case column_height:
            return tr("height");
            break;
        case column_weight:
            return tr("weight");
            break;
        }
    }
    return QVariant();
}

QVariant StudentModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    int col = index.column();
    auto info = m_studentList.at(row);
    if (role == Qt::DisplayRole)
    {
        switch (col)
        {
        case column_name:
            return info.name;
            break;
        case column_age:
            return QString::number(info.age);
            break;
        case column_height:
            return QString::number(info.height);
            break;
        case column_weight:
            return QString::number(info.weight);
            break;
        }
    }
    else if (role == Qt::UserRole)
    {
        return QVariant::fromValue<Student>(m_studentList[row]);
    }
    return QVariant();
}
3、添加筛选过滤model文件, studentproxymodel.h,studentproxymodel.cpp
studentproxymodel.h


#include 
#include "studentmodel.h"

class StudentProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT
public:
    explicit StudentProxyModel(QObject *parent = nullptr);

protected:
    // 返回true表示source的资源包含在代理model中
    virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;

};

#include "studentproxymodel.h"

StudentProxyModel::StudentProxyModel(QObject *parent)
    : QSortFilterProxyModel{parent}
{

}

bool StudentProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    QModelIndex source = sourceModel()->index(source_row, 0, source_parent);
    // 资源Enttiy节点进行过滤
    Student student = source.data(Qt::UserRole).value<Student>();
    //过滤条件:如果年龄小于20,或身高小于170,或体重小于50,则不显示,返回false
    if(student.age < 20)
    {
        return false;
    }
    if(student.height < 170)
    {
        return false;
    }
    if(student.weight < 50)
    {
        return false;
    }
    return true;
}

4、在widget.cpp中添加测试代码
widget.cpp


#include "widget.h"
#include "ui_widget.h"
#include 
#include 
#include "studentmodel.h"
#include "studentproxymodel.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QHBoxLayout* layout = new QHBoxLayout(this);
    this->setLayout(layout);
    QTableView* tableView = new QTableView(this);
    layout->addWidget(tableView);

    Student stu1;
    stu1.age = 18;
    stu1.name = "sandy";
    stu1.height = 170;
    stu1.weight = 50;

    Student stu2;
    stu1.age = 23;
    stu1.name = "alice";
    stu1.height = 168;
    stu1.weight = 55;

    Student stu3;
    stu1.age = 20;
    stu1.name = "make";
    stu1.height = 178;
    stu1.weight = 60;

    Student stu4;
    stu1.age = 22;
    stu1.name = "jason";
    stu1.height = 180;
    stu1.weight = 70;

    QList<Student> studentList;
    studentList.clear();
    studentList.append(stu1);
    studentList.append(stu2);
    studentList.append(stu3);
    studentList.append(stu4);

    StudentModel* model = new StudentModel(this);
    StudentProxyModel* proxyModel = new StudentProxyModel(this);
    proxyModel->setSourceModel(model);
    tableView->setModel(proxyModel);
    model->setInfo(studentList);
}

Widget::~Widget()
{
    delete ui;
}
5、结果显示满足过滤条件(只有make和jason满足过滤条件)

用自定义的QSortFilterProxyModel实现条件过滤,使qtableview中只显示满足条件的行信息_第2张图片

你可能感兴趣的:(QT,qt)