c++ - 当 QObject 通过引用传递时,C++ 信号的参数在 QML 中显示为“未定义”
问题描述
我有一个带有连接到 QML 处理程序的信号的 C++ 对象。但是,即使我将参数传递给信号,QML 参数仍显示为undefined
.
使用Balloon
和Air
作为 custom QObject
s,我将Balloon
's 信号连接void popped(Air const& air, int volume, QString message);
到 QML 处理程序:
气球.qml:
import QtQuick 2.12
import QtQuick.Controls 2.12
import ReproImpl 0.1 as Impl
Item {
id: root
width: 500
height: 500
property int sharpness: 50
readonly property Impl.Balloon impl: Impl.Balloon {
onPopped: {
// Output: {}
console.log(JSON.stringify(arguments));
// TypeError: cannot read property 'type' of undefined
console.log("Bang!", air.type, volume, message);
}
}
Button {
anchors.centerIn: parent
text: "Click me"
onClicked: {
console.log("Clicked!");
impl.prick(sharpness)
}
}
}
主.cpp:
#include <QGuiApplication>
#include <QObject>
#include <QQmlEngine>
#include <QQuickView>
namespace my::ns {
// Used as a parameter of the signal
class Air : public QObject {
Q_OBJECT
Q_PROPERTY(QString type READ type)
public:
Air(QString type, QObject* parent = nullptr)
: QObject{parent}
, type_{type}
{}
Air(QObject* parent = nullptr)
: Air{"", parent}
{}
QString type() const { return type_; }
private:
QString type_;
};
class Balloon : public QObject {
Q_OBJECT
public:
Balloon(int toughness, QObject* parent = nullptr)
: QObject{parent}
, toughness{toughness}
{}
Balloon(QObject* parent = nullptr)
: Balloon{10, parent}
{}
Q_SIGNALS:
void popped(Air const& air, int volume, QString message);
public Q_SLOTS:
void prick(int sharpness)
{
if (sharpness > toughness) {
Air air{"Hello"};
Q_EMIT popped(air, 10, "POP!");
}
}
private:
int toughness;
};
void registerModule()
{
qmlRegisterModule("ReproImpl", 0, 1);
qmlRegisterType<Air>("ReproImpl", 0, 1, "Air");
qmlRegisterType<Balloon>("ReproImpl", 0, 1, "Balloon");
qmlProtectModule("ReproImpl", 0);
}
}
int main(int argc, char** argv)
{
QGuiApplication app(argc, argv);
my::ns::registerModule();
QQuickView window(QUrl("Balloon.qml"));
window.show();
return app.exec();
}
#include "main.moc"
我能做些什么来解决这个问题?
这发生在 Qt 5.12.0 和 5.13.0 中。
解决方案
无论出于何种原因,QML 都不支持参考信号参数。您正在air
通过const&
:
void popped(Air const& air, int volume, QString message);
要使其正常工作,您需要传递一个非常量指针:
void popped(Air* air, int volume, QString message);
// ...
void prick(int sharpness)
{
if (sharpness > toughness) {
Air air{"Hello"};
Q_EMIT popped(&air, 10, "POP!");
}
}
请注意,将指针传递给已分配的堆栈是安全的air
;QML 不拥有它的所有权:
当数据从 C++ 传输到 QML 时,数据的所有权始终属于 C++ [除非从显式 C++ 方法调用返回 QObject]。
推荐阅读
- c# - 使用 RestSharp 从 API 返回 JSON 数据
- vba - 使用 ByRef 更新记录集字段
- python - 提取多个 XML 文件上所有标签之间的文本,并将提取的文本复制到 csv 文件
- laravel - 在 Laravel 和 Vue 之间共享数据的正确方式
- python - 如何在 tensorflow keras 中引用地面实况变量?
- hadoop - 无法将数据从 Pig 存储到 hbase
- reactjs - useForm隐藏的嵌套文件输入不起作用
- sql - 用单个列从另一个表更新一个表中的多个列?
- python - 如何通过不让它重复结果来正确循环范围
- sql - 标准多连接性能问题