为什么我不能分配这个Qt属性?

时间:2017-12-13 23:13:10

标签: c++ qt qml qt4 qt5

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类的简化版

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元数据系统注册课程

#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文件的snipet

import ExampleModule 1.0

ApplicationWindow {
    visible: true
    width: 800
    height: 480

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

1 个答案:

答案 0 :(得分:1)

您必须将该属性声明为指针。根据{{​​3}}:

,所有QObject都应该被操作为指针
  

无复制构造函数或赋值运算符QObject

     

没有副本   构造函数也不是赋值运算符。这是设计的。其实,   它们被声明,但是在宏的私有部分   Q_DISABLE_COPY()。实际上,所有Qt类都派生自QObject(直接   或间接)使用此宏来声明其复制构造函数和   赋值运算符是私有的。推理发现于   关于Qt对象模型页面上的身份与价值的讨论。

     

主要结果是你应该使用指向QObject的指针(或者   你的QObject子类,否则你可能会想要使用它   您的QObject子类作为值。例如,没有副本   构造函数,您不能使用QObject的子类作为值   存储在其中一个容器类中。你必须存储指针。

在你的情况下:

#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

可以在以下docs中找到功能示例。