QT C++ 到 QML 无法连接
QT C++ to QML can not be connected
我有以下代码:
class Boundaries: public QObject{
Q_OBJECT
enum Type{
in,
out
};
QDateTime m_startTimeBoundary{};
QDateTime m_endTimeBoundary{};
QDateTime m_from{};
QDateTime m_to{};
Q_PROPERTY(QDateTime fromDate READ getFromDate NOTIFY emitSignal1)
Q_PROPERTY(QDateTime toDate READ getToDate NOTIFY emitSignal1)
QDateTime getFromDate(){
return m_from;
}
QDateTime getToDate(){
return m_to;
}
public: signals:
void emitSignal1();
public:
void initBoundaries(const QDateTime& start,const QDateTime& end){
if (m_startTimeBoundary.isNull() && m_endTimeBoundary.isNull()){
m_startTimeBoundary = start;
m_endTimeBoundary = end;
}
}
void myClass(const QDateTime& origin, qint64 diffMs, Type type)
{
//..some code..
emit emitSignal1();
}
Q_INVOKABLE void myClassIn(const QDateTime& origin, qint64 diffMs){
myClass(origin, diffMs, Type::in);
}
Q_INVOKABLE void myClassOut(const QDateTime& origin, qint64 diffMs){
myClass(origin, diffMs, Type::out);
}
};
我的 C++ 模型:
class MyCustomModel: public QObject{
Q_OBJECT
..some code..
Q_PROPERTY(Boundaries* myClass READ getmyClass)
Boundaries* m_myClass;
Boundaries* getmyClass(){
return m_myClass;
}
.. some other code..
}
我的 QML 连接问题来了:
MyButton {
anchors.verticalCenter: timeFilterRow.verticalCenter
onClicked:{
var x = getDataX()
var y = getDataY()
myCustomModel.myClass.myClassIn(_org, diff)
}
}
但我收到一条错误消息,提示 Boundaries
未知。你们中的任何人都可以帮助我理解我在这里做错了什么吗?还是我遗漏了什么?
您是否曾经创建过 Boundaries
类型的对象?
在 C 或 C++ 中声明指针不会自动实例化对象,成员甚至不会默认初始化为 nullptr
,因此它可以是内存的任何地址。如果真是这样,你很幸运它没有崩溃。
如果您在调试模式下在正确的平台上使用正确的编译器,那么指针会自动初始化为 nullptr
.
Qml 从 invokables/slots/properties 可用的类型信息(QMetaObject,https://doc.qt.io/qt-5.14/qmetaobject.html)中读取。如果指针是 nullptr
,Qml 无法访问该对象的类型信息,因为它不存在。
下一点:如果你想在 Q_PROPERTY
中使用它,你必须在 Qt 类型系统中注册你的类型:
Q_DECLARE_METATYPE(Boundaries)
https://doc.qt.io/qt-5.14/qmetatype.html#Q_DECLARE_METATYPE
Qt 将属性类型打包为 QVariant
(查看类型擦除模式)。要使用它,你必须告诉 Qt,你的类型将需要它的代码(默认情况下它不会为你定义的所有 类 生成代码,严格符合“你只为你用什么”).
根据我对 myCustomModel.myClass.myClassIn(_org, diff)
的理解,您正试图从 C++ 环境中调用一个对象的函数,但您实际上是在创建一个 MyCustomModel
类型的新实例,这需要 QML 知道classBoundaries
不是注册类型 (qmlRegisterType
) 以使其可实例化,我猜您正在寻找一种方法来传递 C++ 对象以使其在 QML 中可访问
如果是这种情况,您可以通过声明上下文来实现此目的 属性:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyCustomModel model;
engine.rootContext()->setContextProperty(QStringLiteral("modelinstance"), &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml"));
return app.exec();
}
那么您应该能够从 QML 中调用此对象实例:
if (modelinstance)
modelinstance.myclass.myClassIn(_org, diff)
我有以下代码:
class Boundaries: public QObject{
Q_OBJECT
enum Type{
in,
out
};
QDateTime m_startTimeBoundary{};
QDateTime m_endTimeBoundary{};
QDateTime m_from{};
QDateTime m_to{};
Q_PROPERTY(QDateTime fromDate READ getFromDate NOTIFY emitSignal1)
Q_PROPERTY(QDateTime toDate READ getToDate NOTIFY emitSignal1)
QDateTime getFromDate(){
return m_from;
}
QDateTime getToDate(){
return m_to;
}
public: signals:
void emitSignal1();
public:
void initBoundaries(const QDateTime& start,const QDateTime& end){
if (m_startTimeBoundary.isNull() && m_endTimeBoundary.isNull()){
m_startTimeBoundary = start;
m_endTimeBoundary = end;
}
}
void myClass(const QDateTime& origin, qint64 diffMs, Type type)
{
//..some code..
emit emitSignal1();
}
Q_INVOKABLE void myClassIn(const QDateTime& origin, qint64 diffMs){
myClass(origin, diffMs, Type::in);
}
Q_INVOKABLE void myClassOut(const QDateTime& origin, qint64 diffMs){
myClass(origin, diffMs, Type::out);
}
};
我的 C++ 模型:
class MyCustomModel: public QObject{
Q_OBJECT
..some code..
Q_PROPERTY(Boundaries* myClass READ getmyClass)
Boundaries* m_myClass;
Boundaries* getmyClass(){
return m_myClass;
}
.. some other code..
}
我的 QML 连接问题来了:
MyButton {
anchors.verticalCenter: timeFilterRow.verticalCenter
onClicked:{
var x = getDataX()
var y = getDataY()
myCustomModel.myClass.myClassIn(_org, diff)
}
}
但我收到一条错误消息,提示 Boundaries
未知。你们中的任何人都可以帮助我理解我在这里做错了什么吗?还是我遗漏了什么?
您是否曾经创建过 Boundaries
类型的对象?
在 C 或 C++ 中声明指针不会自动实例化对象,成员甚至不会默认初始化为 nullptr
,因此它可以是内存的任何地址。如果真是这样,你很幸运它没有崩溃。
如果您在调试模式下在正确的平台上使用正确的编译器,那么指针会自动初始化为 nullptr
.
Qml 从 invokables/slots/properties 可用的类型信息(QMetaObject,https://doc.qt.io/qt-5.14/qmetaobject.html)中读取。如果指针是 nullptr
,Qml 无法访问该对象的类型信息,因为它不存在。
下一点:如果你想在 Q_PROPERTY
中使用它,你必须在 Qt 类型系统中注册你的类型:
Q_DECLARE_METATYPE(Boundaries)
https://doc.qt.io/qt-5.14/qmetatype.html#Q_DECLARE_METATYPE
Qt 将属性类型打包为 QVariant
(查看类型擦除模式)。要使用它,你必须告诉 Qt,你的类型将需要它的代码(默认情况下它不会为你定义的所有 类 生成代码,严格符合“你只为你用什么”).
根据我对 myCustomModel.myClass.myClassIn(_org, diff)
的理解,您正试图从 C++ 环境中调用一个对象的函数,但您实际上是在创建一个 MyCustomModel
类型的新实例,这需要 QML 知道classBoundaries
不是注册类型 (qmlRegisterType
) 以使其可实例化,我猜您正在寻找一种方法来传递 C++ 对象以使其在 QML 中可访问
如果是这种情况,您可以通过声明上下文来实现此目的 属性:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyCustomModel model;
engine.rootContext()->setContextProperty(QStringLiteral("modelinstance"), &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml"));
return app.exec();
}
那么您应该能够从 QML 中调用此对象实例:
if (modelinstance)
modelinstance.myclass.myClassIn(_org, diff)