在 QTreeWidget 中排序时调试断言(无效比较器)
Debug assertion (invalid comparator) when sorting in a QTreeWidget
我在 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
可以包含 federate
和 federatenamespace
子项目.
我想对它们进行排序,因此在任何级别,我首先有所有 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);
}
我的猜测写在评论中:
You don't consider the case that (type() == Type::Federate) && (other.type() == Type::FederateNamespace)
which should result in false
regardless of the text(0)
s. I know this VS error and it results from an assert which checks !(B < A)
for A < B
to ensure that the strict order is achieved/granted by the predicate.
我对固定 less 运算符的建议:
bool FederateListItem::operator<(const QTreeWidgetItem& other) const {
if (type() != other.type()) return type() == Type::FederateNamespace;
return text(0) < other.text(0);
}
我在 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
可以包含 federate
和 federatenamespace
子项目.
我想对它们进行排序,因此在任何级别,我首先有所有 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);
}
我的猜测写在评论中:
You don't consider the case that
(type() == Type::Federate) && (other.type() == Type::FederateNamespace)
which should result infalse
regardless of thetext(0)
s. I know this VS error and it results from an assert which checks!(B < A)
forA < B
to ensure that the strict order is achieved/granted by the predicate.
我对固定 less 运算符的建议:
bool FederateListItem::operator<(const QTreeWidgetItem& other) const {
if (type() != other.type()) return type() == Type::FederateNamespace;
return text(0) < other.text(0);
}