cannot resolve Qt's QMetaObject::invokeMethod: No such method error
我正在尝试开发一个通用函数,该函数确定两个QObject是否相等。为了使之成为可能,被比较的函数必须具有"等于"方法,该方法将比较每个函数中的各个函数值,如果它们均相等,则返回true。此外,必须使用Q_INVOKABLE声明此"等于"方法。
但是,当我尝试为'equals'方法调用invokeMethod时,它失败,并显示错误" QMetaObject :: invokeMethod:没有这样的方法F1 :: equals(QObject *)(QObject *)"。 >
这是我的测试项目和文件:
项目文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
assert1.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #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 |
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #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(); } |
运行测试会产生以下输出:
1 2 3 4 5 6 | 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起作用?
您遇到的错误是invokeMethod只等待Q_SLOT或Q_INVOKABLE的名称,不需要或不需要签名,但是您传递给它
1 2 3 4 | if(!QMetaObject::invokeMethod(o1,"equals", Qt::DirectConnection, Q_RETURN_ARG(bool, rslt), Q_ARG(QObject*, o2))) |