Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法解析Qt';s QMetaObject::invokeMethod:没有此类方法错误_Qt_Qmetaobject - Fatal编程技术网

无法解析Qt';s QMetaObject::invokeMethod:没有此类方法错误

无法解析Qt';s QMetaObject::invokeMethod:没有此类方法错误,qt,qmetaobject,Qt,Qmetaobject,我试图开发一个通用函数来确定两个QoObject是否相等。为了实现这一点,被比较的函数必须有一个“equals”方法,该方法比较每个函数中的各种函数值,如果它们都相等,则返回true。因此,必须使用Q_INVOKABLE声明此“equal”方法 但是,当我尝试为“equals”方法调用invokeMethod时,它失败了,并显示一个错误“QMetaObject::invokeMethod:没有这样的方法F1::equals(QObject*)(QObject*)” 这是我的测试项目和文件: 项目

我试图开发一个通用函数来确定两个QoObject是否相等。为了实现这一点,被比较的函数必须有一个“equals”方法,该方法比较每个函数中的各种函数值,如果它们都相等,则返回true。因此,必须使用Q_INVOKABLE声明此“equal”方法

但是,当我尝试为“equals”方法调用invokeMethod时,它失败了,并显示一个错误“QMetaObject::invokeMethod:没有这样的方法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
#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


如何让invokeMethod工作?

在您的案例中,错误在于invokeMethod只等待Q_插槽或Q_INVOKABLE的名称,不需要或想要签名,但您正在传递它
QMetaObject::normalizedSignature(“equals(QObject*)”
,返回“equals(QObject*)”,因此解决方案就是传递equals:

if(!QMetaObject::invokeMethod(o1, "equals",
    Qt::DirectConnection,
    Q_RETURN_ARG(bool, rslt),
    Q_ARG(QObject*, o2)))
如果(!QMetaObject::invokeMethod(o1,“等于”,
Qt::DirectConnection,
返回参数(布尔、rslt),

Q_ARG(QObject*,o2))
My bad。我没有检查我为f1粘贴的内容。它修复了它,谢谢@AllenKempe如果我的答案对你有帮助,那么别忘了标记为正确。如果你不知道怎么做,那么检查
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"
if(!QMetaObject::invokeMethod(o1, "equals",
    Qt::DirectConnection,
    Q_RETURN_ARG(bool, rslt),
    Q_ARG(QObject*, o2)))