根据Qt文档,如果变体包含自定义类型, QVariant::operator==
无法正常工作:
bool QVariant :: operator ==(const QVariant&v)const将此QVariant与v进行比较,如果它们相等则返回true;否则返回false . 在自定义类型的情况下,不调用它们的相等运算符 . 而是比较值的地址 .
你怎么能让这个为你的自定义类型表现得有意义?在我的例子中,我将枚举值存储在QVariant中,例如
在 Headers 中:
enum MyEnum { Foo, Bar };
Q_DECLARE_METATYPE(MyEnum);
功能中的某个地方:
QVariant var1 = QVariant::fromValue<MyEnum>(Foo);
QVariant var2 = QVariant::fromValue<MyEnum>(Foo);
assert(var1 == var2); // Fails!
为了使这个断言成为现实,我需要做些什么?
我理解为什么它不起作用 - 每个变体都存储枚举值的单独副本,因此它们具有不同的地址 . 我想知道如何改变我在变体中存储这些值的方法,以便这不是一个问题,或者它们都引用相同的底层变量 .
这对我来说可能需要通过平等比较来解决问题 . 上下文是我使用此枚举作为 QComboBox
中的项目中的UserData,我希望能够使用 QComboBox::findData
来查找与特定枚举值对应的项目索引 .
3 回答
显而易见的答案是使用
var1.value<MyEnum>() == var2.value<MyEnum>()
来转换数据以进行比较,但这需要您在比较时知道类型 . 看起来在你的情况下这可能是可能的 .如果您只是使用枚举,您还可以将其转换为int以存储在QVariant中 .
编辑:有关搜索QComboBox的说明,请uses the model of the combo box to find the data . 具体来说,它使用QAbstractItemModel的match()函数来检查是否相等 . 幸运的是,这个函数是虚函数,所以你可以在子类中覆盖它 .
尝试hack qvariant,按原型定义函数
并将其设置为qvariant处理程序;要使用qvariant qt,请使用Handler:
此示例演示如何破解qvariant调试输出并转换为字符串 . 这是一个非常简单的示例,您需要为您解决问题 . “标识符”是我的自定义类型 .
您必须创建函数并将其设置为处理程序 . 在使用之前不要忘记在main.cpp中调用
HackVariant::hackIt()
(var1 == var2) .Qt 5的解决方案
自5.2版本开始,Qt就开箱即用 . 见QVariant::operator==和QMetaType::registerComparators .
Qt 4的解决方案
如果你还是(或者不想)升级到Qt 5,你可以使用我为我的一个项目编写的 CustomVariantComparator 类 .
您可以按如下方式使用它 . 假设我们有一个实现
operator==
的类Foo
,应该在QVariant
中使用:然后,只需将
Q_DEFINE_COMPARATOR
宏放在Foo
的实现旁边(即在Foo.cpp
文件中,但不在Foo.h
文件中):接下来, after 构造您的
QApplication
(或QCoreApplication
)实例,启用自定义变量比较器(这只需要执行一次):现在,以下代码片段将按预期工作(即调用
Foo::operator==
) .