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

发布于 12-11 07:59 字数 305 浏览 0 评论 0原文

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

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

1、10、100、1000、101、102、...

但我需要这个结果:

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

我使用 CSV 文件来填充表格。

I have a QTableWidget and the first column contains numbers from 1 to 1000. Now I need to sort the table based on this first column.

I'm using the function sortItems(int column, Qt::AscendingOrder), but it is displayed as:

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

Yet I need this result:

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

I'm using a CSV file for populating the table.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

卷耳2024-12-18 07:59:47

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

如果让 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
  • QDateTimeEditQDateTime
  • ...

The values are sorted as strings because you stored them as such in the model.

The QVariant can remember the original type of the data if you let it do the conversion itself, and the comparison operator from that type will be used when sorting:

// 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);    

The cell editor will also adapt to the type of the QVariant:

  • QSpinBox for int,
  • QDoubleSpinBox for double and float,
  • QDateTimeEdit for QDateTime
  • ...
成熟稳重的好男人2024-12-18 07:59:47

最简单的方法可能是子类化 QTableWidgetItem 然后实现 <运算符要聪明地认识到您正在对数字而不是字符串进行排序。

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

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

The easiest way is probably to subclass QTableWidgetItem and then implement the < operator to be smart about the fact that you're sorting numbers and not strings.

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

Then when you're populating your table you can pass it instances of your custom items that know how to sort themselves properly instead of the generic ones.

人海汹涌2024-12-18 07:59:47

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

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

table.setSortingEnabled(False)

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

('    '+numStr)[-4:]

3)填充表格后,打开排序:

table.setSortingEnabled(True)

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

One way that worked in my situation was

1) before filling the table, turn off sorting:

table.setSortingEnabled(False)

2) pad the number strings with blanks and make all strings in the column have the same length:

('    '+numStr)[-4:]

3) after filling the table, turn on sorting:

table.setSortingEnabled(True)

This fixed the row sorting problem and the numerical order.

作妖2024-12-18 07:59:47

我不知道过去接受的答案是否有效,但对于 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] == '

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

myTableWidget->setItem(row, col, new TableNumberItem("$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(); } };

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

请注意,此类必须仅与数字一起使用,它不会正确对字符串进行排序(情况也是如此)与接受的答案)。

I don't know if the accepted answer used to work, but with Qt5.1, it doesn't.
In order to work, the operator< definition has to match the virtual definition from qtablewidget.h.

Another interesting addition is to sort items that have numbers, but start with a currency sign ($ or for instance) or end with %.

Here is the updated code:

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] == '

Then, you add the items that contain numbers using something like this:

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

Note that this class must be used with numbers only, it will not sort strings correctly (as is also the case with the accepted answer).

|| 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(); } };

Then, you add the items that contain numbers using something like this:

Note that this class must be used with numbers only, it will not sort strings correctly (as is also the case with the accepted answer).

爱*していゐ2024-12-18 07:59:47

我遇到了同样的问题,@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();
        }
    };

I had same problem and the The answer of @Chris worked for me!
but a little modification is need. I can't comment. so I write here.

   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();
        }
    };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文