子类化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();
}
完整代码可私信发送,谢谢!