子类化QAbstractTableModel,实现table列排序和整列拖动功能

2023-11-16

子类化QAbstractTableModel,实现table列排序和整列拖动功能

本程序基于Qt5.9.9,Qt creator 4.11.0实现。
效果图

在这里插入图片描述

1、子类化QAbstractTableModel

主要是实现QAbstractTableModel中的rowCount、columnCount、data这三个纯虚函数;

headerData是用来实现上方和左侧的头显示的接口,这里我也重新override了。

下面看主要代码:

头文件MyTableModel.h

#ifndef MYTABLEMODEL_H
#define MYTABLEMODEL_H
#include <QAbstractTableModel>
#include <vector>
#include <QDateTime>

typedef struct StuInfo
{
    QString id_;
    QString name_;
    int age_;
    float score_;
    QDateTime time_;
}STUINFO;

class MyTableModel : public QAbstractTableModel
{
public:
    MyTableModel(QObject *parent = 0);
    // 设置数据源
    void setStudents(const std::vector<STUINFO> &students);
    // 主要override的函数
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const override;
    // 排序用到的函数
    void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
    bool lessThan(const QVariant &left,const QVariant &right);

private:
    // 数据源
    std::vector<STUINFO> m_students;
    // 上方表格显示的头名称
    QStringList headers;
};

#endif // MYTABLEMODEL_H

rowCount、columnCount、data、headerData接口的具体实现

int MyTableModel::rowCount(const QModelIndex &parent) const
{
    // 源数据数量
    return m_students.size();
}

int MyTableModel::columnCount(const QModelIndex &parent) const
{
    // 头数量
    return headers.size();
}

QVariant MyTableModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();
    switch(role){
            // 对齐模式
    case Qt::TextAlignmentRole:
        return int(Qt::AlignHCenter | Qt::AlignVCenter);
    case Qt::DisplayRole:
        int row = index.row();
        int column = index.column();
        switch(column){
        case 0:
            return m_students[row].id_;
        case 1:
            return m_students[row].name_;
        case 2:
            return m_students[row].age_;
        case 3:
            return m_students[row].score_;
        case 4:
            return m_students[row].time_;
        default:
            return QVariant();
        }
    }
    return QVariant();
}

QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role != Qt::DisplayRole)
        return QVariant();
    if(orientation == Qt::Horizontal){
        // 水平方向的就是上方显示的header
        return headers[section];
    }else{
        // 垂直方向就是左侧显示的header,这里用section+1的方式返回,效果就是1,2....
        return section + 1;
    }
    return QVariant();
}

2、实现案列排序功能

首先需要在QTableView上设置可以排序,使用setSortingEnabled(true)这个接口进行设置

然后override QAbstractTableModel接口中的sort接口实现自己的排序方式,代码如下:

void MyTableModel::sort(int column, Qt::SortOrder order)
{
    if(m_students.empty() || column < 0 || column >= headers.size())
        return;

    const bool is_asc = (order == Qt::AscendingOrder);

    std::sort(m_students.begin(),m_students.end(),
              [column,is_asc,this](const STUINFO &left, const STUINFO &right){
       QVariant left_val, right_val;
       switch(column){
       case 0:
           left_val = left.id_;
           right_val = right.id_;
           break;
       case 1:
           left_val = left.name_;
           right_val = right.name_;
           break;
       case 2:
           left_val = left.age_;
           right_val = right.age_;
           break;
       case 3:
           left_val = left.score_;
           right_val = right.score_;
           break;
       case 4:
           left_val = left.time_;
           right_val = right.time_;
           break;
       }
       return is_asc ?
                   lessThan(left_val, right_val):
                   lessThan(right_val,left_val);
    });
    dataChanged(index(0,0),index(m_students.size()-1,headers.size()-1));
}

bool MyTableModel::lessThan(const QVariant &left, const QVariant &right)
{
    qDebug() << "^^^^^^" << left.userType() << "******" << right.userType() << "&&&&" << QMetaType::UnknownType;
    if(left.userType() == QMetaType::UnknownType)
        return false;
    if(right.userType() == QMetaType::UnknownType)
        return true;
    switch (left.userType()) {
    case QMetaType::Int:
        return left.toInt() < right.toInt();
    case QMetaType::Float:
        return left.toFloat() < right.toFloat();
    case QMetaType::Double:
        return left.toDouble() < right.toDouble();
    case QMetaType::QDateTime:
        return left.toDateTime() < right.toDateTime();
    case QMetaType::QString:
        break;
    default:
        break;
    }
    return left.toString().localeAwareCompare(right.toString()) < 0;
}

详情可参考:https://blog.csdn.net/gongjianbo1992/article/details/108674875

3、实现整列拖拽功能

只需要在QTableView设置horizontalHeader的setSectionMovable为true便可。

代码如下:main.cpp

#include <QApplication>
#include "mytablemodel.h"
#include <QTableView>
#include <QHeaderView>
#include <vector>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    std::vector<STUINFO> stus;
    stus.push_back({"1","wangqiang",23,120, QDateTime::fromString("20170112 12:13:14","yyyyMMdd HH:mm:ss")});
    stus.push_back({"2","liuwei",21,110.2, QDateTime::fromString("20170113 12:13:14","yyyyMMdd HH:mm:ss")});
    stus.push_back({"3","zhaoqian",22,150.2, QDateTime::fromString("20170112 15:13:14","yyyyMMdd HH:mm:ss")});
    stus.push_back({"4","wuxue",25,112.3, QDateTime::fromString("20170114 12:21:14","yyyyMMdd HH:mm:ss")});
    stus.push_back({"5","lifei",24,134.2, QDateTime::fromString("20170122 12:22:14","yyyyMMdd HH:mm:ss")});
    stus.push_back({"6","qianjiang",22,120.1, QDateTime::fromString("20170212 13:13:14","yyyyMMdd HH:mm:ss")});
    MyTableModel model;
    model.setStudents(stus);

    QTableView view;
    view.setModel(&model);
    view.setAlternatingRowColors(true);
    // 设置排序功能
    view.setSortingEnabled(true);
    // 设置水平头可拖动功能
    view.horizontalHeader()->setSectionsMovable(true);
    view.show();
    return a.exec();
}

完整代码可私信发送,谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子类化QAbstractTableModel,实现table列排序和整列拖动功能 的相关文章

随机推荐