【问题标题】:Can't create C++ class object in qml "Cannot assign object to list property "data""无法在 qml 中创建 C++ 类对象“无法将对象分配给列表属性“数据””
【发布时间】:2016-10-07 20:00:24
【问题描述】:

我有一个痛苦的问题,我为此浪费了很多时间。我需要帮助,因为我还没有任何想法。

来了。我正在 Windows 8.1 上的 Qt Creator 中使用 qml 编写 qt 快速应用程序。创建了我自己的名为“one”的 C++ 类。通过以下方式注册:

qmlRegisterType<One>("OneClass", 1, 0, "One");

在我导入的 qml 文件中:

import OneClass 1.0

到目前为止,一切都运行良好。但后来我决定创建共享库,我把我的“一个”C++ 类放在那里。将单独的项目创建为 New project->Library->C++ Library。建立名为“mainlib”的库,一切都很好。通过在 .pro 文件中添加字符串将此库连接到我的应用程序:

DEPENDPATH += ../lib/mainlib
INCLUDEPATH += ../lib/mainlib
LIBS += -L../lib/build-mainlib-Desktop_Qt_5_7_0_MinGW_32bit-Release/release -lmainlib

运行项目,这就是我遇到这个问题的时刻:

QQmlApplicationEngine 加载组件失败

qrc:/main.qml:18 无法将对象分配给列表属性“数据”

断言:文件 C:\Program >Files\Qt\5.7\mingw53_32\include/QtCore/qlist.h 中的“!isEmpty()”,第 341 行

我的“one.h”文件片段:

#ifndef ONE_H
#define ONE_H

#include "mainlib_global.h"
#include <QObject>

class MAINLIBSHARED_EXPORT One : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString  port_number READ get_port_number WRITE set_port_number)
    Q_PROPERTY(QString  port_speed READ get_port_speed WRITE set_port_speed)
    Q_PROPERTY(QString  x READ get_x WRITE set_x)
    Q_PROPERTY(QString  y READ get_y WRITE set_y)

public:
    One();
    ~One();

    QString get_port_number(void);
    ...

signals:
    void portOpened(QString str);
    ...

private:
    QString port_number;
    QString x;
    QString y;
};

#endif // ONE_H

“mainlib_global.h”:

#ifndef MAINLIB_GLOBAL_H
#define MAINLIB_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(MAINLIB_LIBRARY)
#  define MAINLIBSHARED_EXPORT Q_DECL_EXPORT
#else
#  define MAINLIBSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // MAINLIB_GLOBAL_H

“mainlib.pro”:

QT       -= gui

TARGET = mainlib
TEMPLATE = lib

DEFINES += MAINLIB_LIBRARY

SOURCES += one.cpp

HEADERS += one.h\
        mainlib_global.h

unix {
    target.path = /usr/lib
    INSTALLS += target
}

我的“main.qml”文件的一部分,我在其中声明了我的 One 类对象:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.0
import OneClass 1.0
import QtQuick.Dialogs 1.1

Window {
    id: mainWindow
    visible: true
    width: 1000
    height: 720
    minimumWidth: 930
    color: "lightgrey";
    property bool connected: false
    
    // Object declaration
    One {id: objOne}
    ...
    }

我的“main.cpp”文件片段:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
#include "one.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QLocale::setDefault(QLocale::c());
    qmlRegisterType<One>("OneClass", 1, 0, "One");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    ...
    return app.exec();
}

我的应用程序的 .pro 文件:

TEMPLATE = app

DEPENDPATH += ../lib/mainlib
INCLUDEPATH += ../lib/mainlib
LIBS += -L../lib/build-mainlib-Desktop_Qt_5_7_0_MinGW_32bit-Release/release -lmainlib

QT += qml quick serialport
CONFIG += c++11

win32: RC_ICONS += icon.ico

SOURCES += main.cpp \
    #one.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Default rules for deployment.
include(deployment.pri)

HEADERS += \
    #one.h

如果取消注释“one.h”和“one.cpp”以将它们与应用程序一起编译,则不会出现此问题并且一切正常。但是当评论他们使用库时,我得到了这个“无法将对象分配给列表属性“数据””的问题。

我尝试通过右键单击项目->添加库来连接库,但结果是一样的。我已阅读有关此“数据”属性的文档,尝试将对象声明显式分配给“数据”,但得到了相同的结果。试过了:

resources: [
    One {id: objOne}
]

并得到“无法将对象分配给列表属性“资源””。我只是厌倦了解决这个问题。我几乎每一步都描述了你,因为我认为也许我做错了什么?我求救了……

【问题讨论】:

  • one.h的内容是什么?
  • @Patrizio,我在帖子中添加了one.h 的内容。
  • 我们来猜猜一是什么,resource 与什么有关?
  • @folibis, One 是我的 C++ 类,我注册为 qml 类型。我想根据字符串qmlRegisterType&lt;One&gt;("OneClass", 1, 0, "One");import OneClass 1.0,应该很明显了。我尝试将objOne 分配给resources,只要有可能。
  • 我猜你的问题是resource,而不是One 的声明。但你没有具体说明它是什么以及它与什么对象相关。

标签: c++ qt qml shared-libraries


【解决方案1】:

一种可能的解决方案是声明一个新属性并将其绑定到一个新的“One”组件:

Window {
    property One objOne: One { }
}

但是正如您将看到的,这可能会导致其他(线程)问题。不要这样做!

强烈建议您使用 Qt 内置插件机制。它旨在完全满足您的需求:导入外部动态 QML 库。 查看文档:http://doc.qt.io/qt-5/qtqml-modules-cppplugins.html

【讨论】:

  • 谢谢,会记住的。但我就是不明白为什么我的变种不起作用?我认为使用库与与类一起编译项目相同,没有任何变化。还有关于共享库的文档:doc.qt.io/qt-4.8/sharedlibrary.html。甚至维基:wiki.qt.io/…。应该没问题。
  • 使用静态库与与类一起编译是一样的。动态库有点不同。如果您确实需要动态 qml 库,请按照文档中的说明创建它。这也将减少两个项目之间的依赖关系。
  • 重做插件。在发布模式下一切正常,但在调试时出现错误:plugin cannot be loaded for module。从发布中放入调试目录插件文件夹。但它不起作用。据我了解,插件被编译为普通库,可以在其他项目中使用,甚至不是 qml?唯一不同的是它是作为插件连接的?
  • 哦,我完全傻了。我试图在调试模式下使用已发布的插件。在调试模式下重建插件,一切都开始工作。谢谢帮忙!
猜你喜欢
  • 2011-06-06
  • 2017-11-01
  • 1970-01-01
  • 2021-06-30
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
相关资源
最近更新 更多