Qt之 QTableWidget 列排序

Qt之 QTableWidget 列排序

1、常规的QTableWidget的排序接口

void QTableView::setSortingEnabled(bool enable)  // 允许点击表头进行排序
void QTableWidget::sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder)  // 排序接口

例子:

table->setSortingEnabled(true);  	// 运行排序
table->sortItems(0);				// 对 0 列排序, 默认升序

2、含有数字字符的字符串排序

常规的排序是以QString序进行排序,也就是u16序,如下图:

Qt之 QTableWidget 列排序_第1张图片

对于混杂有数字的字符串排序如上图,就不太符合人的认知。

对于混合有数字的排序,需要重写 QTableWidgetItem的比较函数 operator<():

bool QTableWidgetItem::operator<(const QTableWidgetItem &other) const

所以自定义排序则需要扩展QTableWidgetItem,自定义字符串排序算法很好写,但是不需要。因为Qt自身提供了一个十分方便的类 :QCollator

virtual bool operator<(const QTableWidgetItem& other) const override
{
    QCollator collator;
    collator.setNumericMode(true);
    auto ret = collator.compare(this->text(), other.text());
    if (ret < 0)
        return true;
    else
        return false;
}

Qt之 QTableWidget 列排序_第2张图片

3、保存原始序

在构造item的时候,顺便保存行号为原始序

item = new ATableWidgetItem;
item->setData(ATableWidgetItem::OriginSort,0);  // 保存原始序

使用一个 flag 来控制排序

virtual bool operator<(const QTableWidgetItem& other) const override
{
    if (sortToOrigin) {
        return this->data(OriginSort).toInt() < other.data(OriginSort).toInt();
    } else {
        QCollator collator;
        collator.setNumericMode(true);
        auto ret = collator.compare(this->text(), other.text());
        if (ret < 0)
            return true;
        else
            return false;
    }
}

完整Demo

Qt之 QTableWidget 列排序_第3张图片

#include 
#include 
#include 
#include 
#define qout qDebug() << __FILE__ << __LINE__
#define qrand QRandomGenerator::global()

QStringList testStr = { "hello" };

/**
 * @brief 扩展 QTableWidgetItem 类, 重写 operator<() 函数
 */
class ATableWidgetItem : public QTableWidgetItem {
public:
    using QTableWidgetItem::QTableWidgetItem; // 继承构造
    enum {
        OriginSort = Qt::UserRole + 1
    };

public:
    virtual bool operator<(const QTableWidgetItem& other) const override
    {
        if (sortToOrigin) {
            return this->data(OriginSort).toInt() < other.data(OriginSort).toInt();
        } else {
            QCollator collator;
            collator.setNumericMode(true);
            auto ret = collator.compare(this->text(), other.text());
            if (ret < 0)
                return true;
            else
                return false;
        }
    }
    static bool sortToOrigin; // 声明原始序标志
};

bool ATableWidgetItem::sortToOrigin = false; // 定义原始序标志

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    auto HBox = new QHBoxLayout(&w);

    auto table = new QTableWidget;
    HBox->addWidget(table);

    auto btn = new QPushButton("显示表格原始序");
    HBox->addWidget(btn);

    auto row = 5, col = 3;
    table->setRowCount(row);
    table->setColumnCount(col);

    for (int i = 0; i < row; ++i) {
        for (int j = 0; j < col; ++j) {
            auto* item = table->item(i, j);
            if (!item) {
                item = new ATableWidgetItem;
                //                item = new QTableWidgetItem;
                table->setItem(i, j, item);
                if (j == 0)
                    item->setData(ATableWidgetItem::OriginSort, i);
            }
            auto txt = testStr[qrand->bounded(testStr.length())]
                + "_"
                + QString::number(qrand->bounded(20)) + "_world";
            item->setText(txt);
        }
    }
    table->setSortingEnabled(true);

    QObject::connect(btn, &QPushButton::clicked, [&] {
        ATableWidgetItem::sortToOrigin = true;
        table->sortItems(0);
        table->horizontalHeader()->setSortIndicator(-1, Qt::AscendingOrder);
        ATableWidgetItem::sortToOrigin = false;
    });

    w.resize(500, 300);
    w.show();
    return a.exec();
}

你可能感兴趣的:(#,Qt,案例,qt,排序算法,开发语言)