QT中QTreeWidget的叶子QTreeWidgetItem默认只支持大小写排序,但QTreeWidgetItem提供了“<”的虚函数,重写一下就可以实现自定义排序规格:
QTreeWidgetItem:
void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order)
enum Qt::SortOrder
This enum describes how the items in a widget are sorted.
Constant Value Description
Qt::AscendingOrder 0
The items are sorted ascending e.g. starts with 'AAA' ends with 'ZZZ' in Latin-1 locales
Qt::DescendingOrder 1
The items are sorted descending e.g. starts with 'ZZZ' ends with 'AAA' in Latin-1 locales
假如需要排序的是:
"1","1_1","1_1_1","1_2_1","1_3_1", "1_1_3_1", "1_1_3_1_1", "1_1_3_1_2", "1_1_3_1_3"
这种数据的话,我们的思路是首先用正则表达式匹配字符串中的数值,放入容器中,在对比两个容器中数字的大小,这样就可以根据自己的需要对QTreeWidgetItem进行排序,主要代码如下:
TreeWidgetItem.h
#ifndef TREEWIDGETITEM_H
#define TREEWIDGETITEM_H
#include <QTreeWidgetItem>
#include <QRegExp>
class TreeWidgetItem : public QTreeWidgetItem
{
public:
TreeWidgetItem(const QStringList &strings = QStringList(), int type = 0);
~TreeWidgetItem();
private:
bool operator<(const TreeWidgetItem& other) const;
QVector<int> RegNum(QString str) const;
};
#endif // TREEWIDGETITEM_H
TreeWidgetItem.cpp
#include "TreeWidgetItem.h"
TreeWidgetItem::TreeWidgetItem(const QStringList &strings, int type)
: QTreeWidgetItem(strings, type)
{
}
TreeWidgetItem::~TreeWidgetItem()
{
}
bool TreeWidgetItem::operator<(const TreeWidgetItem& other) const
{
QVector<int> vec = RegNum(text(0));
QVector<int> vecother = RegNum(other.text(0));
if (vec.size() != vecother.size())
{
return vec.size() < vecother.size();
}
else
{
for (int i = 0; i < vec.size(); ++i)
{
if (vec[i] != vecother[i])
{
return vec[i] < vecother[i];
}
}
}
return false;
}
QVector<int> TreeWidgetItem::RegNum(QString str) const
{
QVector<int> vec;
QRegExp rx("(\\d+)");
int pos = 0;
while ((pos = rx.indexIn(str, pos)) != -1) {
vec.push_back(rx.cap(1).toInt());
pos += rx.matchedLength();
}
return vec;
}
插入叶子完成之后,每个父节点调用排序函数:
sortItems(0, Qt::AscendingOrder);
测试数据如下:
PolyonUnit unit1;
unit1.name = "1";
PolyonUnit unit1_1;
unit1_1.name = "1_1";
PolyonUnit unit1_2;
unit1_2.name = "1_2";
PolyonUnit unit1_1_1;
unit1_1_1.name = "1_1_1";
PolyonUnit unit1_2_1;
unit1_2_1.name = "1_2_1";
PolyonUnit unit1_3_1;
unit1_3_1.name = "1_3_1";
PolyonUnit unit1_1_2;
unit1_1_2.name = "1_1_2";
PolyonUnit unit1_1_3;
unit1_1_3.name = "1_1_3";
PolyonUnit unit1_1_3_1;
unit1_1_3_1.name = "1_1_3_1";
PolyonUnit unit1_1_3_2;
unit1_1_3_2.name = "1_1_3_2";
PolyonUnit unit1_1_3_1_1;
unit1_1_3_1_1.name = "1_1_3_1_1";
PolyonUnit unit1_1_3_1_2;
unit1_1_3_1_2.name = "1_1_3_1_2";
PolyonUnit unit1_1_3_1_3;
unit1_1_3_1_3.name = "1_1_3_1_3";
unit1_1_3_1._children.push_back(unit1_1_3_1_1);
unit1_1_3_1._children.push_back(unit1_1_3_1_2);
unit1_1_3_1._children.push_back(unit1_1_3_1_3);
unit1_1_3._children.push_back(unit1_1_3_1);
unit1_1_3._children.push_back(unit1_1_3_2);
//unit1_2._children.push_back(unit1_1_3_1);
unit1_1._children.push_back(unit1_1_1);
unit1_1._children.push_back(unit1_2_1);
unit1_1._children.push_back(unit1_3_1);
unit1_1._children.push_back(unit1_1_2);
unit1_1._children.push_back(unit1_1_3);
unit1._children.push_back(unit1_1);
//unit1._children.push_back(unit1_2);
pdata.push_back(unit1);
PolyonUnit是我自己定义的数据结构,类似QTreeWidgetItem的树形结构,详细代码稍后上传,测试结果如下: