2014-07-08 56 views
7

我有一個超類Common,它繼承自QObject。然後我有一個類Item,它繼承了CommonQMetaObject :: invokeMethod:使用繼承時沒有這樣的方法

COMMON.H

class Common : public QObject { 
    Q_OBJECT 

public: 
    // some methods 
}; 

Item.h

class Item : public Common { 
    Q_OBJECT 

public: 
    // some methods 
    void test(QString value); 
}; 

Item.cpp

void Item::test(QString value) { 
    qDebug() << value; 
} 

我想用QMetaObject::invokeMethod來動態調用一個函數。 所以我在Item類中實現了一個測試函數,它只需要一個字符串。

Item* item = new Item(); 
QMetaObject::invokeMethod(item, "test", Qt::DirectConnection, Q_ARG(QString, "1234")); 

這是行不通的。我得到以下錯誤:QMetaObject::invokeMethod: No such method Common::test(QString),這是完全可以和罰款,因爲Common類沒有test函數。

我怎麼能告訴QMetaObject::invokeMethod,它應該調用Item類的方法?

+0

是否'類Item'有'Q_OBJECT'宏?爲了使元對象系統知道槽,這是必需的。添加插槽仍然是可能的,但它們只會是正常的功能。此外,該功能首先需要是一個插槽(或「Q_INVOKABLE」方法)。 – leemes

+0

不,它沒有。我添加了它,但仍然出現錯誤。我應該編輯我的問題並將必要的源代碼放入其中,或者您有其他提示嗎? – Niklas

+0

當您添加宏時,重新運行qmake。它需要掃描宏的文件,以便知道它需要在其上運行'moc'。 Qt的另一個缺陷......;) – leemes

回答

15

QMetaObject::invokeMethod只能調用Qt元對象系統已知的方法。這些是插槽和「可調用」功能,後者的功能是在它們之前使用關鍵字Q_INVOKABLE

因此,要麼寫:

class Item : public Common { 
    Q_OBJECT 

public slots: 
    // ^^^^^ 
    void test(QString value); 
}; 

或:

class Item : public Common { 
    Q_OBJECT 

public: 
    Q_INVOKABLE void test(QString value); 
    //^^^^^^^^^ 
}; 
+0

'Q_INVOKABLE void test(QString value);'爲我做了。謝謝! – Niklas

+1

@Niklas是的,我在編輯中添加了它:)如果函數從未用於信號插槽連接,我更喜歡'Q_INVOKABLE'。但對於很多功能,只是說'公共插槽:'少打字:) – leemes