【问题标题】:Qt - How to run a C++ function when QML button is clicked? Using QQmlApplicationEngineQt - 单击 QML 按钮时如何运行 C++ 函数?使用QQmlApplicationEngine
【发布时间】:2014-09-12 07:41:57
【问题描述】:

myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QDebug>
#include <QObject>

class MyClass : public QObject
{
public:
    MyClass();

public slots:
    void buttonClicked();
    void buttonClicked(QString &in);
};

#endif // MYCLASS_H

myclass.cpp

#include "myclass.h"

MyClass::MyClass()
{
}

void MyClass::buttonClicked()
{
    // Do Something
}

void MyClass::buttonClicked(QString &in)
{
    qDebug() << in;
}

ma​​in.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <myclass.h>
#include <QQmlContext>

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

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    MyClass myClass;  // A class containing my functions

    // Trying to "SetContextProperty" as I saw people do it to achieve C++/QML connection
    QQmlContext * context = new QQmlContext(engine.rootContext());
    context->setContextProperty("_myClass", &myClass);

    return app.exec();
}

我想在 myClass 类中使用一个函数,该函数在单击 QML 按钮时采用 QString 参数..

当我编译和运行时.. 一切都很顺利。 但是当我点击按钮..它在调试器中显示这个错误:

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

~>“我的 QML 文件中的第 80 行”:

74:    MouseArea {
75:        id: mouseArea1
76:        anchors.fill: parent
77:        hoverEnabled: true;
78:        onEntered: { rectangle1.border.width = 2 }
79:        onExited: { rectangle1.border.width = 1 }
80:        onClicked: _myClass.buttonClicked("Worked?")
81:    }

编辑:(至于错误导致编译错误)

正如 @Jairo 所建议的,所有类都必须继承自 QObject。

仍在寻找解决我的主要问题的方法。

【问题讨论】:

  • 它给出的错误是什么?
  • @lthreed 对不起老兄,我已经编辑了问题并添加了所有必要的信息。
  • 来吧...您甚至没有提到哪一行给出了错误,也没有包括您的班级...错误一定来自您的班级。
  • MyClass 是基于 QObject 类的吗?
  • @Jairo 是的,就是这样! myclass 应该继承自 QObject。但不幸的是,这也不能解决主要问题..如何更改代码以使其可以使用 QML 中的 C++ 函数(myClass.buttonClicked(QString)),例如:[_myClass.buttonClicked("JJJ")]?谢谢:)

标签: c++ qt qml qt5 qt-quick


【解决方案1】:

哦哦。这里有几个问题。 (代码甚至可以编译吗?)

首先要做的事情。将某些内容传递给 QML 引擎的根属性时,您无法创建新上下文 - 您必须直接使用根上下文,如下所示:

engine.rootContext()->setContextProperty("_myClass", &myClass);

接下来,类定义有一些问题。在下面的代码中查看我的 cmets:

class MyClass : public QObject
{
    // This macro is required for QObject support.  You should get a compiler
    // error if you don't include this.
    Q_OBJECT

public:
    // QObjects are expected to support a parent/child hierarchy.  I've modified
    // the constructor to match the standard.
    explicit MyClass(QObject *parent = 0);

public slots:
    // This method needs to take either a QString or a const reference to one.
    // (QML doesn't support returning values via the parameter list.)
    void buttonClicked(const QString& in);
};

构造函数的实现应该将父类传递给基类:

MyClass::MyClass(QObject *parent) :
    QObject(parent)
{
}

【讨论】:

  • 事实上,您不必将 Q_INVOKABLE 附加到插槽。所有的 slot 都被 moc 自动处理为可调用函数。
  • @xylosper 我不知道,但一个快速的实验证明你是对的。我会更新我的答案。感谢您的更正和信息!
  • 关于构造函数的最后一点,为了完整性:如果不修复,一个很好的捕获和一个令人讨厌的惊喜,尽管与这个问题中的问题无关(这里构造函数被调用,没有参数)。
  • QQmlApplicationEngine 在我的应用程序中运行良好。我不确定 _audGrabber 是什么,您没有在问题中包含 QML 的那部分。
  • 对不起,它工作正常。只需删除 void buttonClicked(); 即可使其工作,我认为 QML 无法识别这种类型的函数声明。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-09-05
  • 2015-08-13
  • 1970-01-01
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多