使用QT的容器时,可以使用qt的排序函数qStableSort、qUpperBound详情可以参考此博主文章:https://blog.csdn.net/qq_43445867/article/details/134431883?spm=1001.2101.3001.6650.16&utm_medium=distribute.wap_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-16-134431883-blog-24697431.237%5Ev3%5Ewap_relevant_t0_download&depth_1-utm_source=distribute.wap_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-16-134431883-blog-24697431.237%5Ev3%5Ewap_relevant_t0_download
直接上代码:
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMap>
#include <QVariant>
#include <QDateTime>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
typedef QMap<QString,QVariant> RecordRow;//表示表格其中一行数据
typedef QList<RecordRow> LstRecord;//表示整个表格的数据
enum E_SORT_TYPE
{
E_SORT_ASCENDING = 0,//升序
E_SORT_DESCENDING //降序
};
struct compareStruct
{
compareStruct(const int& nSortType,const QString& strKey,const int& nDataType)
{
m_nSortType = nSortType;
m_strSortKey = strKey;
m_nDataType = nDataType;
}
bool operator()(const RecordRow &a, const RecordRow &b)//排序函数
{
if(m_nSortType == E_SORT_ASCENDING)
{
switch(m_nDataType)
{
case QVariant::Int:
return a.value(m_strSortKey).toInt() < b.value(m_strSortKey).toInt();
break;
case QVariant::Double:
return a.value(m_strSortKey).toDouble() < b.value(m_strSortKey).toDouble();
break;
case QVariant::String:
return a.value(m_strSortKey).toString() < b.value(m_strSortKey).toString();
break;
case QVariant::DateTime:
return a.value(m_strSortKey).toDateTime() < b.value(m_strSortKey).toDateTime();
break;
case QVariant::ULongLong:
return a.value(m_strSortKey).toULongLong() < b.value(m_strSortKey).toULongLong();
break;
default:
return false;
break;
}
}
else
{
switch(m_nDataType)
{
case QVariant::Int:
return a.value(m_strSortKey).toInt() > b.value(m_strSortKey).toInt();
break;
case QVariant::Double:
return a.value(m_strSortKey).toDouble() > b.value(m_strSortKey).toDouble();
break;
case QVariant::String:
return a.value(m_strSortKey).toString() > b.value(m_strSortKey).toString();
break;
case QVariant::DateTime:
return a.value(m_strSortKey).toDateTime() > b.value(m_strSortKey).toDateTime();
break;
case QVariant::ULongLong:
return a.value(m_strSortKey).toULongLong() > b.value(m_strSortKey).toULongLong();
break;
default:
return false;
break;
}
}
}
int m_nSortType; //升序还是降序
QString m_strSortKey; //排序关键字 即表格的列标题
int m_nDataType; //表格该列的数据类型
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_insert_clicked();
void on_tableWidgetHeaderViewClicked(int index);
private:
void initData();
void updateTableWidget();
private:
Ui::Widget *ui;
LstRecord m_LstData;//多线程加锁
compareStruct* m_pCompare = nullptr;//多线程加锁
};
#endif // WIDGET_H
cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QtEndian>
#include <QRandomGenerator>
#pragma execution_character_set("utf-8")
//pro中设置以下代码和 代码中设置 #pragma execution_character_set("utf-8")存在一个即可,否则会编译报错
//msvc {
// QMAKE_CFLAGS += /utf-8
// QMAKE_CXXFLAGS += /utf-8
//}
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("测试程序");
initData();
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_tableWidgetHeaderViewClicked(int index)
{
static bool bAsc = true;//升序
QTableWidgetItem *pItem = nullptr;
pItem = ui->tableWidget->horizontalHeaderItem(index);
if(pItem == nullptr)
{
return;
}
bool bRes = false;
int nDataType = pItem->data(Qt::UserRole).toInt(&bRes);
QString strKey = pItem->text();
int nSortType;
if(bAsc)
{
nSortType = E_SORT_ASCENDING;
}
else
{
nSortType = E_SORT_DESCENDING;
}
if(m_pCompare)
{
m_pCompare->m_nDataType = nDataType;
m_pCompare->m_nSortType = nSortType;
m_pCompare->m_strSortKey = strKey;
}
else
{
m_pCompare = new compareStruct(nSortType,strKey,nDataType);
}
qStableSort(m_LstData.begin(),m_LstData.end(),*m_pCompare);
updateTableWidget();
bAsc = !bAsc;
}
void Widget::initData()
{
// ui->tableWidget->setSortingEnabled(true);//这是表格自动排序,我们不用,用自定义排序数据,再刷新表格
connect(ui->tableWidget->horizontalHeader(),SIGNAL(sectionClicked(int)),this,SLOT(on_tableWidgetHeaderViewClicked(int)));
ui->tableWidget->horizontalHeader()->setSortIndicatorShown(true);//出现升序、降序箭头
ui->tableWidget->setColumnCount(6);
int nColCount = ui->tableWidget->horizontalHeader()->count();
for(int j = 0;j<nColCount;j++)// 也可以初始化自定义设置ui->tableWidget->setHorizontalHeaderItem(0, item0)设置Item
{
QTableWidgetItem *pItem = new QTableWidgetItem;
if(j == 0)
{
int nTmpType = QVariant::String;//不这样填,setData返回值永远为0 ,估计是QVariant::Type类型不为int吧
pItem->setData(Qt::UserRole,nTmpType);
pItem->setText("姓名");
ui->tableWidget->setHorizontalHeaderItem(j,pItem);
}
else if(j==1)
{
int nTmpType = QVariant::String;//不这样填,setData返回值永远为0 ,估计是QVariant::Type类型不为int吧
pItem->setData(Qt::UserRole,nTmpType);
pItem->setText("性别");
ui->tableWidget->setHorizontalHeaderItem(j,pItem);
}
else if(j==2)
{
int nTmpType = QVariant::ULongLong;//不这样填,setData返回值永远为0 ,估计是QVariant::Type类型不为int吧
pItem->setData(Qt::UserRole,nTmpType);
pItem->setText("学号");
ui->tableWidget->setHorizontalHeaderItem(j,pItem);
}
else if(j==3)
{
int nTmpType = QVariant::Int;//不这样填,setData返回值永远为0 ,估计是QVariant::Type类型不为int吧
pItem->setData(Qt::UserRole,nTmpType);
pItem->setText("成绩");
ui->tableWidget->setHorizontalHeaderItem(j,pItem);
}
else if(j==4)
{
int nTmpType = QVariant::Double;//不这样填,setData返回值永远为0 ,估计是QVariant::Type类型不为int吧
pItem->setData(Qt::UserRole,nTmpType);
pItem->setText("身高");
ui->tableWidget->setHorizontalHeaderItem(j,pItem);
}
else if(j==5)
{
int nTmpType = QVariant::DateTime;//不这样填,setData返回值永远为0 ,估计是QVariant::Type类型不为int吧
pItem->setData(Qt::UserRole,nTmpType);
pItem->setText("入学日期");
ui->tableWidget->setHorizontalHeaderItem(j,pItem);
}
}
//姓名、性别、学号、成绩、升高、入学日期
RecordRow tmp1;
tmp1.insert("姓名","张三");
tmp1.insert("性别","男");
tmp1.insert("学号",5120146604);
tmp1.insert("成绩",QRandomGenerator::global()->bounded(550, 620));
tmp1.insert("身高",1.55 + QRandomGenerator::global()->bounded(0.35));
tmp1.insert("入学日期",QDateTime::currentDateTime().addSecs(QRandomGenerator::global()->bounded(-10000, 150000)));
RecordRow tmp2;
tmp2.insert("姓名","李四");
tmp2.insert("性别","男");
tmp2.insert("学号",5120146605);
tmp2.insert("成绩",QRandomGenerator::global()->bounded(550, 620));
tmp2.insert("身高",1.55 + QRandomGenerator::global()->bounded(0.35));
tmp2.insert("入学日期",QDateTime::currentDateTime().addSecs(QRandomGenerator::global()->bounded(-10000, 150000)));
RecordRow tmp3;
tmp3.insert("姓名","燕青");
tmp3.insert("性别","女");
tmp3.insert("学号",5120146606);
tmp3.insert("成绩",QRandomGenerator::global()->bounded(550, 620));
tmp3.insert("身高",1.55 + QRandomGenerator::global()->bounded(0.35));
tmp3.insert("入学日期",QDateTime::currentDateTime().addSecs(QRandomGenerator::global()->bounded(-10000, 150000)));
RecordRow tmp4;
tmp4.insert("姓名","柳九");
tmp4.insert("性别","女");
tmp4.insert("学号",5120146607);
tmp4.insert("成绩",QRandomGenerator::global()->bounded(550, 620));
tmp4.insert("身高",1.55 + QRandomGenerator::global()->bounded(0.35));
tmp4.insert("入学日期",QDateTime::currentDateTime().addSecs(QRandomGenerator::global()->bounded(-10000, 150000)));
RecordRow tmp5;
tmp5.insert("姓名","王五");
tmp5.insert("性别","男");
tmp5.insert("学号",5120146608);
tmp5.insert("成绩",QRandomGenerator::global()->bounded(550, 620));
tmp5.insert("身高",1.55 + QRandomGenerator::global()->bounded(0.35));
tmp5.insert("入学日期",QDateTime::currentDateTime().addSecs(QRandomGenerator::global()->bounded(-10000, 150000)));
m_LstData.append(tmp1);
m_LstData.append(tmp2);
m_LstData.append(tmp3);
m_LstData.append(tmp4);
m_LstData.append(tmp5);
updateTableWidget();
}
void Widget::updateTableWidget()
{
// ui->tableWidget->clearContents();
int nColCount = ui->tableWidget->horizontalHeader()->count();
int nRowCount = m_LstData.size();
if(ui->tableWidget->rowCount() != nRowCount)
{
ui->tableWidget->setRowCount(nRowCount);
}
QTableWidgetItem* pItem = nullptr;
for(int i = 0;i<nRowCount;i++)
{
for(int j = 0;j<nColCount;j++)
{
pItem = ui->tableWidget->item(i,j);
if(pItem == nullptr)
{
pItem = new QTableWidgetItem;
QString strKey = ui->tableWidget->horizontalHeaderItem(j)->text();
QVariant var = m_LstData.at(i).value(strKey);
if(var.isNull())
{
continue;
}
pItem->setData(Qt::DisplayRole,var);
// pItem->setText(var.toString());
ui->tableWidget->setItem(i,j,pItem);
}
else
{
QString strKey = ui->tableWidget->horizontalHeaderItem(j)->text();
QVariant var = m_LstData.at(i).value(strKey);
pItem->setData(Qt::DisplayRole,var);
}
}
}
}
void Widget::on_pushButton_insert_clicked()
{
RecordRow tmp5;
tmp5.insert("姓名","王差");
tmp5.insert("性别","男");
tmp5.insert("学号",5120146609);
tmp5.insert("成绩",QRandomGenerator::global()->bounded(550, 620));
tmp5.insert("身高",1.55 + QRandomGenerator::global()->bounded(0.35));
tmp5.insert("入学日期",QDateTime::currentDateTime().addSecs(QRandomGenerator::global()->bounded(-10000, 150000)));
//计划设计 这个模拟数据在排序的中间,如成绩为 1 5 3 6 9 7,这个成绩为2 那么降序结果应该为 9 7 6 5 3 2 1
// m_LstData.append(tmp5);
LstRecord::Iterator itr;
itr = qUpperBound(m_LstData.begin(),m_LstData.end(),tmp5,*m_pCompare);//与qLowerBound原理为2分法进行查找后插入原容器
//qUpperBound查找大于目标值的第一个元素,qLowerBound查找小于目标值的第一个元素
m_LstData.insert(itr,tmp5);
updateTableWidget();
}