为什么我不能分配这个 Qt 属性? [英] Why can I not assign this Qt property?
问题描述
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屋!