为什么我不能给这个Qt赋值属性?

Why can I not assign this Qt property?

Qt 在运行时抛出以下错误。

Unable to assign LIMITS_T to LIMITS_T

我假设 Qt 需要更多的元数据信息,但我不知道我错过了什么。我已尽一切努力声明元类型:

limits.h

class LIMITS_T : public QObject{
    Q_OBJECT
    Q_PROPERTY(float min READ readMin WRITE writeMin NOTIFY minChanged)

public:
    LIMITS_T() : QObject() {}
    LIMITS_T(const LIMITS_T& limit) : QObject()
    {
        this->min = limit.min;
    }

    float min = 0;

    float readMin() { return min; }
    void writeMin(float min) { this->min = min; }

    bool operator = (const LIMITS_T &limit)
    {
        this->min = limit.min;
    }

signals:
    void minChanged();
};

Q_DECLARE_METATYPE(LIMITS_T)

这是 splitBarGauge 的简化版本class

splitDialGauge.h

class SplitDialGauge : public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(LIMITS_T limits READ getLimits WRITE setLimits NOTIFY limitsChanged)

public:
    SplitDialGauge(QQuickItem *parent = 0);

protected:
    LIMITS_T limits;
    virtual LIMITS_T getLimits();
    virtual void setLimits(LIMITS_T value);
}

splitDialGauge.cpp

#include "splitBarGauge.h"

SplitDialGauge::SplitDialGauge(QQuickItem *parent = 0);
    : QQuickPaintedItem(parent)
{
}

LIMITS_T SplitDialGauge::getLimits()
{
    return this->limits;
}

void SplitDialGauge::setLimits(LIMITS_T limits)
{
    this->limits = limits;
    update();
}

我用 Qt 元数据系统注册 class

#include "limits.h"
#include "splitDialGauge.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    qmlRegisterType<SplitDialGauge>("ExampleModule", 1, 0, "SplitDialGauge");
    qmlRegisterType<LIMITS_T>("ExampleModule", 1, 0, "Limits");
    qRegisterMetaType<LIMITS_T>();

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

这是 QML 文件的片段

import ExampleModule 1.0

ApplicationWindow {
    visible: true
    width: 800
    height: 480

    SplitDialGauge {
        Limits {
            id: qtyLimits
            min: 4
        }
        height: 200
        width: 50
        limits: qtyLimits
    }
}

您必须将 属性 声明为指针。根据 docs:

所有 QObject 都应该作为指针进行操作

No Copy Constructor or Assignment Operator QObject

has neither a copy constructor nor an assignment operator. This is by design. Actually, they are declared, but in a private section with the macro Q_DISABLE_COPY(). In fact, all Qt classes derived from QObject (direct or indirect) use this macro to declare their copy constructor and assignment operator to be private. The reasoning is found in the discussion on Identity vs Value on the Qt Object Model page.

The main consequence is that you should use pointers to QObject (or to your QObject subclass) where you might otherwise be tempted to use your QObject subclass as a value. For example, without a copy constructor, you can't use a subclass of QObject as the value to be stored in one of the container classes. You must store pointers.

你的情况:

#ifndef SPLITDIALGAUGE_H
#define SPLITDIALGAUGE_H

#include "limits_t.h"

#include <QPainter>
#include <QQuickPaintedItem>    

class SplitDialGauge : public QQuickPaintedItem {
    Q_OBJECT
    Q_PROPERTY(LIMITS_T *limits READ getLimits WRITE setLimits NOTIFY limitsChanged)
    LIMITS_T *limits;    
public:
    SplitDialGauge(QQuickItem *parent = 0) : QQuickPaintedItem(parent), limits(nullptr) { }
    void paint(QPainter *painter) {
        [...]
    }    
    LIMITS_T *getLimits() const { return limits; }
    void setLimits(LIMITS_T *value) {
        if (limits == value) return;
        limits = value;
        [...]
        emit limitsChanged();
    }     
signals:
    void limitsChanged();
};
#endif // SPLITDIALGAUGE_H

可以在以下link.

中找到一个功能示例