为什么我不能分配这个 Qt 属性? [英] Why can I not assign this Qt property?

查看:57
本文介绍了为什么我不能分配这个 Qt 属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

无法将 LIMITS_T 分配给 LIMITS_T

我假设 Qt 需要更多元数据信息,但我不知道我错过了什么.我已经做了一切来声明元类型:

limits.h

class LIMITS_T : public QObject{Q_OBJECTQ_PROPERTY(float min READ readMin WRITE writeMin NOTIFY minChanged)上市:LIMITS_T() : QObject() {}LIMITS_T(const LIMITS_T& limit) : QObject(){this->min = limit.min;}浮动分钟= 0;浮动 readMin() { 返回分钟;}void writeMin(float min) { this->min = min;}bool 运算符 = (const LIMITS_T &limit){this->min = limit.min;}信号:void minChanged();};Q_DECLARE_METATYPE(LIMITS_T)

这是 splitBarGauge 类的简化版本

splitDialGauge.h

class SplitDialGauge : public QQuickPaintedItem{Q_OBJECTQ_PROPERTY(LIMITS_T 限制 READ getLimits WRITE setLimits NOTIFY limitsChanged)上市:SplitDialGauge(QQuickItem *parent = 0);受保护:LIMITS_T 限制;虚拟 LIMITS_T getLimits();虚拟无效 setLimits(LIMITS_T 值);}

splitDialGauge.cpp

#include "splitBarGauge.h"SplitDialGauge::SplitDialGauge(QQuickItem *parent = 0);: QQuickPaintedItem(父){}LIMITS_T SplitDialGauge::getLimits(){返回此->限制;}void SplitDialGauge::setLimits(LIMITS_T 限制){this->limits = 限制;更新();}

然后我在 Qt 元数据系统中注册了这个类

#include "limits.h"#include "splitDialGauge.h"int main(int argc, char *argv[]){QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);qmlRegisterType("ExampleModule", 1, 0, "SplitDialGauge");qmlRegisterType("ExampleModule", 1, 0, "Limits");qRegisterMetaType();QQmlApplicationEngine 引擎;engine.load(QUrl(QLatin1String("qrc:/main.qml")));如果 (engine.rootObjects().isEmpty())返回-1;返回 app.exec();}

这是来自 QML 文件的片段

import ExampleModule 1.0应用程序窗口{可见:真实宽度:800高度:480SplitDialGauge {限制{id:数量限制分钟:4}高度:200宽度:50限制:数量限制}}

解决方案

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

<块引用>

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

既没有副本构造函数或赋值运算符.这是设计使然.实际上,它们被声明,但在带有宏的私有部分中Q_DISABLE_COPY().实际上,所有从 QObject 派生的 Qt 类(直接或间接)使用这个宏来声明它们的复制构造函数和赋值运算符是私有的.推理在Qt 对象模型页面上关于 Identity vs Value 的讨论.

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

就你而言:

#ifndef SPLITDIALGAUGE_H#define SPLITDIALGAUGE_H#include "limits_t.h";#include <QPainter>#include 类 SplitDialGauge :公共 QQuickPaintedItem {Q_OBJECTQ_PROPERTY(LIMITS_T *limits READ getLimits WRITE setLimits NOTIFY limitsChanged)LIMITS_T *限制;上市:SplitDialGauge(QQuickItem *parent = 0) : QQuickPaintedItem(parent), limits(nullptr) { }无效油漆(QPainter *画家){[...]}LIMITS_T *getLimits() const { 返回限制;}void setLimits(LIMITS_T *value) {如果(限制 == 值)返回;限制 = 值;[...]发出limitsChanged();}信号:void limitChanged();};#endif//SPLITDIALGAUGE_H

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

Qt throws the following error at runtime.

Unable to assign LIMITS_T to LIMITS_T

I assume that Qt needs more meta data information, but I don't know what I missing. I have done everything to declare the metatype:

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)

This is a simplified version of the 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();
}

And I register the class with the Qt Metadata system

#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();
}

Here is a snipet from the QML file

import ExampleModule 1.0

ApplicationWindow {
    visible: true
    width: 800
    height: 480

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

解决方案

You must declare the property as a pointer. All QObjects are supposed to be manipulated as pointers, according to the docs:

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.

In your case:

#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

A functional example can be found in the following link.

这篇关于为什么我不能分配这个 Qt 属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆