如何在QTableWidget中对数据进行排序?

时间:2011-10-21 11:22:32

标签: qt

我有一个QTableWidget,第一列包含从1到1000的数字。现在我需要根据第一列对表进行排序。

我正在使用函数sortItems(int column, Qt::AscendingOrder),但它显示为:

  

1,10,100,1000,101,102,......

然而我需要这个结果:

  

1,2,3,4 ....,1000。

我正在使用CSV文件填充表格。

5 个答案:

答案 0 :(得分:22)

这些值按字符串排序,因为您将它们存储在模型中。

QVariant如果让它自己进行转换,则可以记住数据的原始类型,并且在排序时将使用该类型的比较运算符:

// Get the value from the CSV file as a numeric type
int valueFromCsvFile = ...;

// don't do this
QTableWidgetItem *item = new QTableWidgetItem(QString::number(valueFromCsvFile));

// but do this instead
QTableWidgetItem *item = new QTableWidgetItem;
item.setData(Qt::EditRole, valueFromCsvFile);    

单元格编辑器也将适应QVariant的类型:

  • QSpinBox代表int
  • QDoubleSpinBox代表doublefloat
  • {li> QDateTimeEdit QDateTime
  • ...

答案 1 :(得分:10)

最简单的方法可能是继承QTableWidgetItem,然后实现<操作员要聪明的是你要排序数字而不是字符串。

class MyTableWidgetItem : public QTableWidgetItem {
    public:
        bool operator <(const QTableWidgetItem &other) const
        {
            return text().toInt() < other.text().toInt();
        }
};

然后,当您填充表格时,您可以传递自定义项目的实例,这些项目知道如何正确排序,而不是通用的。

答案 2 :(得分:2)

在我的情况下有效的方法是

1)在填写表格之前,请关闭排序:

table.setSortingEnabled(False)

2)用空格填充数字字符串,并使列中的所有字符串具有相同的长度:

('    '+numStr)[-4:]

3)填写表格后,打开分类:

table.setSortingEnabled(True)

这解决了行排序问题和数字顺序。

答案 3 :(得分:2)

我不知道接受的答案是否适用,但是在Qt5.1中,它并没有。 为了工作,operator<定义必须与qtablewidget.h中的虚拟定义相匹配。

另一个有趣的补充是对具有数字的项目进行排序,但以货币符号(例如$开头)或以%结尾。

以下是更新后的代码:

class TableNumberItem : public QTableWidgetItem
{
public:
    TableNumberItem(const QString txt = QString("0"))
        :QTableWidgetItem(txt)
    {
    }

    bool operator < (const QTableWidgetItem &other) const
    {
        QString str1 = text();
        QString str2 = other.text();

        if (str1[0] == '$' || str1[0] == '€') {
            str1.remove(0, 1);
            str2.remove(0, 1); // we assume both items have the same format
        }

        if (str1[str1.length() - 1] == '%') {
            str1.chop(1);
            str2.chop(1); // this works for "N%" and for "N %" formatted strings
        }

        double f1 = str1.toDouble();
        double f2 = str2.toDouble();

        return str1.toDouble() < str2.toDouble();
    }
};

然后,使用以下内容添加包含数字的项目:

myTableWidget->setItem(row, col, new TableNumberItem("$0"));

请注意,此类必须仅用于数字,它不会正确排序字符串(与接受的答案一样)。

答案 4 :(得分:0)

我有同样的问题,@ Chris的答案对我有用! 但需要稍加修改。我无法发表评论。所以我在这里写。

   class MyTableWidgetItem : public QTableWidgetItem {
    public:
        bool operator <(const QTableWidgetItem &other) const
        {
            if (text()=="")
                return text().toDouble() > other.text().toDouble();
            else
                return text().toDouble() < other.text().toDouble();
        }
    };