[英]QML/QT How to convert object from C++ to QML?
我花了一段時間,但最終我設法將 JavaScript/QML POJO 轉換為不是從 QObject 派生的自定義對象。
我認為通過一個工作示例更容易理解我的問題。 所以讓我們從這個開始:
struct SomeType { /* Just a plain struct that does not derive from QObject! */ };
SomeType FooFactory::convertQMLToSomeType(const QJSValue& val) {
SomeType result = /*... some kind of conversion takes place here ... */
return result;
}
void FooFactory::registerTypes(QQmlEngine& engine) {
QMetaType::registerConverter<QJSValue, SomeType>(FooFactory::convertQMLToSomeType);
}
它的作用是注冊一個轉換器,用於將QSValue
轉換為SomeType
。 所以現在,每當我在 QML 中做這樣的事情時
my_prop = { "foo": "some plain javascript object" };
假設my_prop
在相應的 C++ 類中像這樣公開:
Q_PROPERTY(SomeType my_prop MEMBER _myProp);
SomeType _myProp;
// Somewhere else outside the class, this is needed for registering the converter
Q_DECLARE_METATYPE(SomeType);
字符串被隱式轉換為SomeType
無需手動操作。
..
偉大的!
但是轉換的相反方向呢? 我需要 QML 來處理字符串,而不是QVariant(SomeType)
對象(QT 在處理元系統時總是在內部使用QVariant
包裝器來存儲用戶定義的類型)。
我已經嘗試過注冊這樣的逆轉換器:
QMetaType::registerConverter<SomeType, QJSValue>(FooFactory::convertBackToQML);
或這個
QMetaType::registerConverter<QVariant(SomeType), QJSValue>(FooFactory::convertBackToQML);
但這些方法都不起作用。 我相信第二行很有前途,但由於注冊靜態元類型的問題,我什至無法編譯那一行。
那么,我將如何解決這個問題? 簡短提醒一下,我無法從QObject
派生SomeType
,是的,我知道這是執行此類操作的最常用方法。
有沒有人有想法? 還是我叫錯了樹? 提前謝謝了!
這可能不是您想要的,但也可能是您唯一的選擇。 您可以圍繞結構創建 QObject 包裝器類。 只需為要公開的結構中的任何值創建屬性。
class SomeWrapper : public QObject
{
Q_OBJECT
Q_PROPERTY(QString someData READ someData WRITE setSomeData NOTIFY someDataChanged)
public:
explicit SomeWrapper(QObject *parent = nullptr) : QObject(parent) {}
QString someData() { return m_struct.someData; }
void setSomeData(QString data)
{
if (data != m_struct.someData)
{
m_struct.someData = data;
emit someDataChanged();
}
}
signals:
void someDataChanged();
private:
SomeType m_struct;
};
如果您想像使用普通 JavaScript 對象一樣操作您的結構,那么另一個選項可能是使用QVariantMap
作為您的屬性的類型。 然后,您可以在屬性的 getter 和 setter 中定義所需的轉換:
class Whichever : public QObject {
Q_OBJECT
Q_PROPERTY(QVariantMap my_prop READ myProp WRITE setMyProp)
QVariantMap myProp() const {
QVariantMap map;
map["some_field"] = _myProp.someField;
// Fill the other fields as needed.
return map;
}
void setMyProp(const QVariantMap& map) {
_myProp.someField = map["some_field"].toString();
// Fill the other _myProp fields as needed.
}
};
QVariantMap
和實際 JavaScript 對象之間的轉換將由 QML 引擎自動處理。 嵌套的 JavaScript 對象也應該可以通過嵌套相應的QVariantMap
s 來實現。
當然,這個選項使得屬性聲明不那么明確它對應於哪種類型,如果您需要聲明這種類型的多個屬性,可能需要更多的樣板代碼(您可以為此定義和使用自己的宏)雖然如果需要)。 但這可能是實現您所描述的最簡單方法之一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.