为什么我不能分配此QT属性

Why can I not assign this Qt property?

本文关键字:QT 属性 分配 不能分 不能 为什么      更新时间:2023-10-16

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文件的nipet

import ExampleModule 1.0
ApplicationWindow {
    visible: true
    width: 800
    height: 480
    SplitDialGauge {
        Limits {
            id: qtyLimits
            min: 4
        }
        height: 200
        width: 50
        limits: qtyLimits
    }
}

您必须将属性声明为指针。根据文档,所有Qobject都应该被操纵为指针:

没有复制构造函数或分配运算符qobject

没有副本构造函数或作业操作员。这是设计。实际上,他们被宣布,但在带有宏观的私人部分中q_disable_copy()。实际上,所有来自qobject的QT类(直接或间接)使用此宏来声明其复制构造函数和任务操作员是私人的。推理是在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

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