我正在尝试开发一个通用函数来确定两个 QObjects 是否相等。为了使这成为可能,被比较的函数必须有一个“equals”方法,该方法比较每个函数中的各种函数值,如果它们都相等则返回true。此外,这个“相等”方法必须用 Q_INVOKABLE 声明。
但是,当我尝试为 'equals' 方法调用 invokeMethod 时,它会失败并显示错误“QMetaObject::invokeMethod: No such method F1::equals(QObject*)(QObject*)”。
这是我的测试项目和文件:
项目文件:
CONFIG += c++11 console
CONFIG -= app_bundle
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
HEADERS += \
f1.h \
assert1.h
断言1.h
#ifndef ASSERT1_H
#define ASSERT1_H
#include <QObject>
#include <QDebug>
class Assert1 : public QObject
{
Q_OBJECT
public:
explicit Assert1(QObject *parent = nullptr) {}
static bool isEqual(QString msg, QObject* o1, QObject* o2)
{
if(o1 != nullptr && o2 != nullptr)
{
if(o1->metaObject()->className() != o2->metaObject()->className())
{
qDebug() << msg << " not same class type!";
return false;
}
const QMetaObject* metaObject =o1->metaObject();
int ix = metaObject->indexOfMethod(QMetaObject::normalizedSignature("equals(QObject *)"));
qDebug() << QMetaObject::normalizedSignature("equals(QObject *)");
if(ix == -1)
{
qDebug() << msg << tr("indexOfMethod(\"equals\") returns %1").arg(ix);
return false;
}
else
{
bool rslt = false;
if(!QMetaObject::invokeMethod(o1, QMetaObject::normalizedSignature("equals(QObject *)"),
Qt::DirectConnection,
Q_RETURN_ARG(bool, rslt),
Q_ARG(QObject*, o2)))
qDebug() << msg << tr("invoke method 'equals' failed for %1").arg(o1->metaObject()->className());
if(!rslt)
qDebug() << msg << tr(" objects not equal");
return false;
}
}
qDebug() << msg << "not equal";
}
signals:
public slots:
};
#endif // ASSERT1_H
f1.h
#ifndef F1_H
#define F1_H
#include <QObject>
#include <QDebug>
class F1 : public QObject
{
Q_OBJECT
public:
explicit F1(int p1, QString p2, QObject *parent = nullptr) : QObject(parent)
{
this->p1 = p1;
this->p2 = p2;
}
void setP1(int p) {this->p1 = p;}
void setP2(QString p) {this->p2 = p;}
Q_INVOKABLE bool equals(QObject* other)
{
if(qobject_cast<F1*>(other) != nullptr)
{
if(this->p1 != ((F1*)other)->p1)
return false;
if(this->p2 != ((F1*)other)->p2)
return false;
}
return true;
}
Q_INVOKABLE QString toString()
{
qDebug() << "p1 '" << p1 << " p2 = '" << p2 << "'";
}
signals:
public slots:
private:
int p1;
QString p2;
};
#endif // F1_H
主文件
#include <QCoreApplication>
#include "f1.h"
#include "assert1.h"
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
F1* tf1 = new F1(1, "1");
F1* tf2 = new F1(1, "a");
F1* tf3 = new F1(1, "a");
F1* tf4 = new F1(4, "abc");
qDebug() << "tf1->equals(tf4) returns: " << (tf1->equals(tf4)?"true":"false");
qDebug() << "tf2->equals(tf3) returns: " << (tf2->equals(tf3)?"true":"false");
Assert1::isEqual("should be equal", (QObject*)tf2, (QObject*)tf3);
//return a.exec();
}
运行测试会产生以下输出:
Debugging starts
tf1->equals(tf4) returns: false
tf2->equals(tf3) returns: false
"equals(QObject*)"
QMetaObject::invokeMethod: No such method F1::equals(QObject*)(QObject*)
"should be equal" "invoke method 'equals' failed for F1"
如何让 invokeMethod 工作?