QT QtableWidgetItem 显示格式化数据并按原始数据排序

QT QtableWidgetItem display formated data and sort by original data

QTableWidget 的列中,我想显示一些 double 值。通过执行以下操作,我得到了我想要的显示:

double value = 1234.567;
QTableWidgetItem* qti = new QTableWidgetItem(QString::number(value , 'f', 4));

现在,如果我在 table 上启用排序并对该列中的值进行排序,它将作为字符串排序。所以 90.0000 会比 800.0000 变成 "larger" 例如 (9 > 8).

如果我这样做:

QTableWidgetItem* qti = new QTableWidgetItem();
qti->setData(Qt::DisplayRole, value);

QTableWidgetItem* qti = new QTableWidgetItem(QString::number(value , 'f', 4));
qti->setData(Qt::DisplayRole, value);

我可以正确地对我的列进行排序,但是我 "lose" 格式化(12.0000 显示为 12)。

我也这样试过:

QTableWidgetItem* qti = new QTableWidgetItem();
qti->setData(Qt::UserRole, value);
qti->setData(Qt::DisplayRole, QString::number(value, 'f', 4));

如何格式化值的显示,同时仍然启用排序?

(在上面的所有代码片段中,QTableWidgetItems' 由以下人员添加:

table->setItem(rowNumber, colNumber, qti);

其中 table 是 QTableWidget)

你做错了。让我们做对吧。解决方案是继承 QTableWidgetItem.

class CustomTableWidgetItem : public QTableWidgetItem
{

public:

    CustomTableWidgetItem(const QString txt = QString("0"))
        :QTableWidgetItem(txt)
    {
    }

    bool operator <(const QTableWidgetItem& other) const
    {
        qDebug() << "Sorting numbers";
        return text().toFloat() < other.text().toFloat();
       // text() is part of QTableWidgetItem, so you can write it as QTableWidgetItem::text().toFloat() as well
    }
};

示例插入

    ui->tableWidget->setSortingEnabled(false);
    ui->tableWidget->insertRow(0);
    ui->tableWidget->setItem(0, 0, new CustomTableWidgetItem(QString::number(90.0005, 'f', 4)));
    ui->tableWidget->insertRow(1);
    ui->tableWidget->setItem(1, 0, new CustomTableWidgetItem(QString::number(800.0003, 'f', 4)));
    ui->tableWidget->insertRow(2);
    ui->tableWidget->setItem(2, 0, new CustomTableWidgetItem(QString::number(200.0010, 'f', 4)));
    ui->tableWidget->insertRow(3);
    ui->tableWidget->setItem(3, 0, new CustomTableWidgetItem(QString::number(200.0020, 'f', 4)));
    ui->tableWidget->setSortingEnabled(true);

排序行为符合预期

升序

90.0005
200.0010
200.0020
800.0003

降序

800.0003
200.0020
200.0010
90.0005

PS: 请记住在插入新项目之前关闭排序。

另一种方法是使用附加到双列的 QStyledItemDelegate。除了实现 QStyledItemDelegate::displayText() 功能外,它不需要做太多事情。

有关详细信息,请参阅 Qt 中心的 QTableView and display of doubles

这是我根据 Mangesh 的回答针对显示百分比的类似问题得出的结论:

class percentageItemC : public QStyledItemDelegate
{
    QString displayText(const QVariant &value, const QLocale &locale) const
    {
        return QString::asprintf("%0.3lf%% ", value.toDouble());
    }
} percentageItem;

这是小数点左边的任意位数,右边的 3 位,以及一个带百分号的长浮点数。然后,做一个

ui->twMyTable->setItemDelegateForColumn(1, &percentageItem);

在你的表格中 class。我也可以将它们重新用于其他列,大概是行。

此方法不会因额外的文本到浮动的转换而减慢速度。您还可以在其中添加一些不错的附加功能,例如逗号、百分号和货币符号。我有这个货币:

class currencyItemC : public QStyledItemDelegate
{
    QString displayText(const QVariant &value, const QLocale &locale) const
    {
        return locale.toCurrencyString(value.toDouble()) + " ";
    }
} currencyItem;

我使用:

QTableWidgetItem *item = new QTableWidgetItem();
item->setData(Qt::EditRole, number);

创建 table 项。它在这些方面很聪明:它创建一个 QVariant,然后根据类型进行排序。这样,您不必将基础数据设置为字符串,但它可以是它具有排序的任何类型。

这些列按数字顺序排序,就像它们被设定的那样,但它们以您喜欢的任何格式显示。 ;}