【问题标题】:How to sort file sizes that are in human readable format?如何对人类可读格式的文件大小进行排序?
【发布时间】:2020-03-10 14:04:11
【问题描述】:

如何对QTableView列中的以下数字进行排序?我使用QSortFilterProxyModel 进行排序。

123 B
1 KB
131 KB
3 GB
322 GB
337 KB
3 MB
555 KB
52 TB

【问题讨论】:

  • 您只需要一个采用人类可读格式并输出数字的函数
  • 可能模型还应该包含一个以字节为单位的原始大小,然后您对其进行排序。如果您不需要,则不必转换 back,而且无论如何,这似乎很容易被本地化等打败。
  • 您将其转换回人类不可读的格式并进行比较。或者您单独保留该格式。
  • 好点。 “为人类”的文本永远不应该被存储,而是在实际为人类显示时计算。 @underscore_d
  • 无论如何,我认为对于 SO,这需要特定代码来显示已完成的操作,因此可以提出解决方案。现在看来太模糊了。

标签: c++ qt sorting qt5


【解决方案1】:

基本上继承QSortFilterProxyModel 并实现lessThan

另外,如果您使用单独的模型角色来存储实际大小(以字节为单位)而不是转换显示的值会更好。在这种情况下,比较方法类似于

class MySortFilterProxyModel : public QSortFilterProxyModel
{
public:
  MySortFilterProxyModel(QObject *parent = 0);

protected:
  bool lessThan(const QModelIndex &left, const QModelIndex &right) const override {
    const auto left_bytes = left.data(SIZE_IN_BYTES_ROLE).toULongLong();
    const auto right_bytes = right.data(SIZE_IN_BYTES_ROLE).toULongLong();

    return left_bytes < right_bytes;
  }
};

如果出于任何原因,您仍然使用显示角色,您应该从索引中获取文本并将字符串转换为字节,然后再进行比较。对于转换函数,您有多种选择,例如将字符串拆分为数字和单位,然后使用查找表获得单位的乘数。

class MySortFilterProxyModel : public QSortFilterProxyModel
{
public:
  MySortFilterProxyModel(QObject *parent = 0);

protected:
  bool lessThan(const QModelIndex &left, const QModelIndex &right) const override {
    const auto left_bytes = toBytes(left.data().toString());
    const auto right_bytes = toBytes(right.data().toString());

    return left_bytes < right_bytes;
  }

private:
  static int64_t toBytes(const QString& size)
  {
    static const QMap<QString, int64_t> s_sizes = {
      {"b", 1},
      {"kb", 1024},
      {"mb", 1024 * 1024},
      {"gb", 1024 * 1024 * 1204},
      {"tb", 1024 * 1024 * 1204 * 1024},
    };

    const auto tokens = size.toLower().split(' ', QString::SkipEmptyParts);
    if (tokens.size() == 0) return 0; // error
    const auto number = tokens[0].toInt();
    if (tokens.size() == 1) return number; // assume bytes
    return number * s_sizes.value(tokens[1], 0); // 0 for unknown units
  }
};

您可以查看更完整的示例,了解如何继承 QSortFilterProxyModel here

【讨论】:

    【解决方案2】:

    当我必须定义我的比较时,我会编写一些继承自 QSortFilterProxyModel 的模型并覆盖虚函数 QSortFilterProxyModel::lessThan。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 2019-04-01
      相关资源
      最近更新 更多