【问题标题】:Debug assertion (invalid comparator) when sorting in a QTreeWidget在 QTreeWidget 中排序时调试断言(无效的比较器)
【发布时间】:2020-06-06 10:32:46
【问题描述】:

我在QTreeWidget 中使用了以下自定义QTreeWidgetItem

#ifndef FEDERATELISTITEM_HPP_
#define FEDERATELISTITEM_HPP_

#include <QTreeWidgetItem>

class FederateListItem : public QTreeWidgetItem {
public:

  enum Type : int {
    Federate = 101,
    FederateNamespace = 102
  };

public:

  FederateListItem(QTreeWidget* parent, Type type);
  FederateListItem(QTreeWidgetItem* parent, Type type);

public:

  bool operator<(const QTreeWidgetItem& other) const;
  bool operator==(const QTreeWidgetItem& other) const;
};

#endif // !FEDERATELISTITEM_HPP_
#include "FederateListItem.hpp"

///////////////////////////////////////////////////////////////////////////////
// CONSTANTS SECTION                                                         //
///////////////////////////////////////////////////////////////////////////////

const QString FederateNamespaceCloseIcon{ ":/icons/FederateNamespaceActive.png" };
const QString FederateIcon(":/icons/FederateActive.png");

///////////////////////////////////////////////////////////////////////////////
// PUBLIC SECTION                                                            //
///////////////////////////////////////////////////////////////////////////////

FederateListItem::FederateListItem(QTreeWidget* parent, Type type) :
  QTreeWidgetItem(parent, static_cast<int>(type)) {
  switch (type) {
  case Type::Federate: {
    setIcon(0, QIcon(FederateIcon));
  } break;
  case Type::FederateNamespace: {
    setIcon(0, QIcon(FederateNamespaceCloseIcon));
  } break;
  default: {

  }
  }
}

FederateListItem::FederateListItem(QTreeWidgetItem* parent, Type type) :
  QTreeWidgetItem(parent, static_cast<int>(type)) {
  switch (type) {
  case Type::Federate: {
    setIcon(0, QIcon(FederateIcon));
  } break;
  case Type::FederateNamespace: {
    setIcon(0, QIcon(FederateNamespaceCloseIcon));
  } break;
  default: {

  }
  }
}

///////////////////////////////////////////////////////////////////////////////
// PUBLIC MEMBER OPERATORS SECTION                                           //
///////////////////////////////////////////////////////////////////////////////

bool FederateListItem::operator<(const QTreeWidgetItem& other) const {
  if ((type() == Type::FederateNamespace) && (other.type() == Type::Federate)) {
    return true;
  }
  return text(0) < other.text(0);
}

bool FederateListItem::operator==(const QTreeWidgetItem& other) const {
  return (type() == other.type()) && (text(0) == other.text(0));
}

基本上我需要使用两种类型的项目:federate 一种是叶子,federatenamespace 一种可以包含federatefederatenamespace 子项目。

我想对它们进行排序,因此,在任何级别,我首先拥有所有 federatenamespace 项目,然后是 federates 一个。就像在 Windows 资源管理器中一样,我首先看到的是文件夹,然后是文件。

为了在我的自定义项目中实现这一点,我添加了一些操作符方法:首先我检查项目的类型并尝试为FederateNamespace 项目提供先例,因此它们应该首先显示。如果类型相同,则按名称排序。

然后我创建QTreeWidget:

  m_tree = new QTreeWidget(this);
  m_tree->setHeaderLabels({ FederatesLabel });
  m_tree->setSortingEnabled(true);

当我开始添加相同类型的项目时,一切似乎都正常,正如我所见:

问题是排序不起作用。您可以在未执行排序的图像中看到。如果我尝试混合元素,则会引发断言。

断言由 Qt 提出并表示比较器无效。

我做错了什么,我该如何解决?

编辑

我遵循了 Scheff 的建议,但稍作调整就无法正常工作。问题是我的运营商方法。这有效:

bool FederateListItem::operator<(const QTreeWidgetItem& other) const {
  if ((type() == Type::FederateNamespace) && (other.type() == Type::Federate)) {
    return false;
  }
  if ((type() == Type::Federate) && (other.type() == Type::FederateNamespace)) {
    return true;
  }
  return text(0) > other.text(0);
}

【问题讨论】:

  • 我猜你的比较器坏了。无论text(0)s 是什么,您都不会考虑(type() == Type::Federate) &amp;&amp; (other.type() == Type::FederateNamespace) 应该导致false 的情况。我知道这个 VS 错误,它是由检查 !(B &lt; A)A &lt; B 的断言引起的,以确保谓词实现/授予严格的顺序。 (我曾经跌入过这个陷阱。);-)
  • 它可以工作(稍作调整),谢谢。如果你回答我会接受。

标签: c++ qt sorting qtreewidget qtreewidgetitem


【解决方案1】:

我的猜测写在评论中:

您不考虑(type() == Type::Federate) &amp;&amp; (other.type() == Type::FederateNamespace) 应该导致false 的情况,而不管text(0)s。我知道这个 VS 错误,它是由一个断言导致的,该断言检查 !(B &lt; A) 中的 A &lt; B 以确保谓词实现/授予严格的顺序。

我对固定 less 运算符的建议:

bool FederateListItem::operator<(const QTreeWidgetItem& other) const {
  if (type() != other.type()) return type() == Type::FederateNamespace;
  return text(0) < other.text(0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多