在QTreeWidget中进行排序时的调试断言(无效比较器)。

问题描述 投票:0回答:1

我有以下自定义 QTreeWidgetItem 我在 QTreeWidget:

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

当我开始添加相同类型的项目时,正如我所看到的那样,一切似乎都正常。

Federates

Groups

问题是排序不起作用。你可以在图像中看到排序没有执行。如果我尝试混合元素,会引发一个断言。

Assertion

这个断言是由Qt提出的,说比较器无效。

我做错了什么,如何解决这个问题?

EDIT

我按照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);
}
c++ qt sorting qtreewidget qtreewidgetitem
1个回答
2
投票

我的猜测写在评论里。

你没有考虑到这样的情况 (type() == Type::Federate) && (other.type() == Type::FederateNamespace) 这将导致 false 无论 text(0)s. 我知道这个VS的错误,它是由一个检查了 !(B < A) 对于 A < B 以确保严格的顺序是由谓词实现的。

我提出的固定少运算符。

bool FederateListItem::operator<(const QTreeWidgetItem& other) const {
  if (type() != other.type()) return type() == Type::FederateNamespace;
  return text(0) < other.text(0);
}
© www.soinside.com 2019 - 2024. All rights reserved.