c++ - 如何将值对象的工厂暴露给 QML?
问题描述
我想制作没有默认构造函数和设置器的值对象,可以从 QML 创建。我将 Factory 的实现作为解决方法,它将像单例一样传递给 QML。但是当我尝试使用它时,我得到“错误:未知方法返回类型:点”,当我关闭应用程序崩溃时,日志中出现“free():无效指针”消息。
点.h:
#ifndef POINT_H
#define POINT_H
#include <QObject>
struct Point
{
Q_GADGET
Q_PROPERTY(int x READ getX CONSTANT)
Q_PROPERTY(int y READ getY CONSTANT)
public:
Point(int x, int y) : x(x), y(y) {
}
Point(const Point& that) = default;
Point& operator=(const Point& that) = default;
int getX() {
return this->x;
}
int getY() {
return this->y;
}
Q_INVOKABLE QString getCoordinates() {
return QString("x=%1; y=%2").arg(this->x, this->y);
}
private:
int x;
int y;
};
#endif // POINT_H
工厂.h:
#ifndef FACTORY_H
#define FACTORY_H
#include <QObject>
#include "point.h"
class Factory : public QObject {
Q_OBJECT
Q_DISABLE_COPY(Factory)
public:
static Factory* instance() {
static Factory factory;
return &factory;
}
Q_INVOKABLE Point newPoint(int x, int y) {
return Point(x, y);
}
private:
Factory() {
}
};
#endif // FACTORY_H
主.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QObject>
#include "factory.h"
#include "point.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterUncreatableType<Point>("test", 1, 0, "Point", "error: no default constructor");
qmlRegisterSingletonType<Factory>("test", 1, 0, "Factory",
[](QQmlEngine* engine, QJSEngine* scriptEngine) -> QObject* {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return Factory::instance();
});
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml:
import QtQuick 2.9
import QtQuick.Controls 2.3
import test 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Component.onCompleted: {
var point = Factory.newPoint(5, 10);
console.log("completed")
}
}
解决方案
推荐阅读
- visual-studio-code - VSCode 个人快捷方式在笔记本编辑器中不起作用
- python - 如何将第一行添加到 csv_read 值?
- c# - 如何轻松地从解决方案迁移所有项目
- sql - ORA-02267: (列类型与引用的列类型不兼容) 尽管数据类型是相同的
- android - 在底部导航视图中选择的每个项目下方添加一行
- javascript - 清除图表缓存
- excel - ActiveX 控件使用参数调用 vba 用户窗体
- c# - 从后面的代码在 Chrome 中打开一个新窗口
- kubernetes - K8s 部署失败但端点工作
- kubernetes - 使用 Kubernetes Executor 运行时,使用 Kubernetes Pod Operator 的作业失败