【问题标题】:Qt: ERROR in Exposing C++ Class to QMLQt:将 C++ 类暴露给 QML 时出错
【发布时间】:2017-12-22 11:06:34
【问题描述】:

我在运行应用程序时不断收到相同的错误:

qrc:/main.qml:13: ReferenceError: _myClass is not defined

错误在哪里?

此外,如果我想将信号 myIntChanged 连接到插槽,我应该将连接放在哪里?在 main.cpp 中还是在构造函数 MyClass 中?

myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>
#include <QString>
#include <QDebug>
#include <QTimer>

class MyClass : public QObject
{
    Q_OBJECT

public:
    MyClass(QObject *parent = 0);

    Q_PROPERTY(int myInt READ getMyInt WRITE setMyInt NOTIFY myIntChanged)
    int myInt;
    inline int getMyInt() { return myInt; }
    inline void setMyInt(int _value) { myInt = _value; }

private:
    void initVariables();

    QTimer *timer;

private slots:
    void editVariables();

signals:
    void myIntChanged();
};

#endif // MYCLASS_H

myclass.cpp

#include "myclass.h"

MyClass::MyClass(QObject *parent) : QObject (parent)
{
    initVariables();

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(editVariables()));
    timer -> start(3000);
}

void MyClass::initVariables()
{
    myInt = 0;
}

void MyClass::editVariables()
{
    myInt = myInt + 1;

    qDebug() << "myclass.cpp: timeout: variables edited.";
}

ma​​in.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "myclass.h"

int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    MyClass *myClass = new MyClass();
    engine.rootContext() -> setContextProperty("_myClass", myClass);

    return app.exec();
}

ma​​in.qml

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Exposed C++ Class")

    Text {
        anchors.top: parent.top; anchors.topMargin: 30
        anchors.left: parent.left; anchors.leftMargin: 30
        text: _myClass.myInt
    }
}

【问题讨论】:

  • 你尝试过从 _myclass 中删除到只是 myclass
  • @Frrank 尝试过,但没有任何改变!此外,qml 文本始终显示“0”,这是初始值,但它不显示任何更新,即使计时器清楚地工作!我使用的是 Qt 5.10.0,如果此信息可能有用
  • 代替文本:_myClass.myInt。试试文字:myClass.myInt
  • @Frrank 已经尝试过了,但它并没有改变什么......
  • 这次是什么错误

标签: c++ qt qml qproperty


【解决方案1】:

问题是因为load()语句正在加载.qml文件,当读取它并验证变量是否存在时,他们意识到这个对象不存在,因为它是通过setContextProperty()传递给他们的,一种可能的解决方案是在加载 .qml 之前将对象传递给它:

int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    MyClass *myClass = new MyClass();
    engine.rootContext()->setContextProperty("_myClass", myClass);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

没有更新是因为没有通过你声明的信号得到通知,正确的做法是每次属性变化时发出一个信号,你必须修改一些方法:

inline void setMyInt(int _value) {
    if(myInt == _value)
        return;
    myInt = _value;
    emit myIntChanged();
}

void MyClass::editVariables()
{
    setMyInt(getMyInt()+1);
    qDebug() << "myclass.cpp: timeout: variables edited.";
}

【讨论】:

  • 是的!错误就这样消失了!!但是为什么 QML 文本不会在计时器超时时更新? @eyllanesc
  • 完美,谢谢,你的回答很清楚! :-) @eyllanesc
猜你喜欢
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多