2

使用 qt 5.5、qt quick controls 1.4 和下面的 qt creator 样板代码:调用 C++ 代码以响应按钮的最正式方式是什么(只是调试文本到屏幕)?

// main cpp
#include <QApplication>
#include <QQmlApplicationEngine>

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

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

     return app.exec();
}

和里面的QML文件qml.qrc

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    Button {
        id: add
        x: 248
        y: 222
        text: qsTr("add")
    }
}

我知道是一个可能的答案,但它看起来是一种非常复杂的方式,只需将按钮挂钩到代码!如果这是使用 Qt 5.5 和 QML 的正式方式,那么这应该是答案。

4

2 回答 2

3

正如您在文档中看到的,您有很多选择:

  • 该类可以注册为可实例化的 QML 类型。这是@BaCaRoZzo 提出的选项
  • 该类可以注册为单例类型
  • 类的实例可以作为上下文属性或上下文对象嵌入到 QML 代码中
  • Qt QML 模块还提供了从 C++ 代码执行反向操作和操作 QML 对象的方法。这是@hyde 提出的选项

在您的情况下,我更喜欢最后一个选项,因为它需要更少的代码行。

例子:

主文件

// main cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myclass.h"

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

     QQmlApplicationEngine engine;
     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
     QObject *item = engine.rootObjects().first();

     MyClass myClass;
     QObject::connect(item, SIGNAL(qmlSignal(QString)),
                      &myClass, SLOT(cppSlot(QString)));

     return app.exec();
}

main.qml

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    signal qmlSignal(string msg)

    Button {
        id: add
        x: 248
        y: 222
        text: qsTr("add")
        onClicked: qmlSignal(text)
    }
}

我的班级.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>
#include <QDebug>

class MyClass : public QObject
{
    Q_OBJECT
public slots:
    void cppSlot(const QString &msg) {
        qDebug() << "Called the C++ slot with message:" << msg;
    }
};

#endif // MYCLASS_H
于 2016-01-26T08:17:26.033 回答
2

我举了一个例子来展示@BaCaRoZzo提到的两种方法:

// main.cpp

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

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

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


    MyClass myclass;

    engine.rootContext()->setContextProperty("_myclass", &myclass);

    QObject *item = engine.rootObjects().first();

    QObject::connect(item, SIGNAL(qmlSignal(QString)), &myclass, SLOT(cppSlot(QString)));

    return app.exec();
}

从 qml 调用的 c++ 类的头文件:

// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0);

signals:


public slots:
    void count();
    void cppSlot(const QString &msg);
};

#endif // MYCLASS_H

及其实施:

#ifndef MY_CLASS_H
#define MY_CLASS_H


// myclass.cpp
#include "myclass.h"
#include <QDebug>

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

}

void MyClass::count()
{
    static int i = 0;
    i++;
    qDebug() << "wow =" + QString::number(i) ;
}

void MyClass::cppSlot(const QString &msg)
{
    qDebug() << "Called the C++ slot with message:" << msg;
}

#endif

带有两个按钮的用户界面 qml 文件显示了两种方法:

//main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    signal qmlSignal(string msg)
    Button {
        id: button
        x: 218
        y: 229
        width: 148
        height: 31
        text: qsTr("run cpp method ctxt prop")
        onClicked: _myclass.count()
    }

    Button {
        id: button1
        x: 218
        y: 300
        width: 148
        height: 23
        text: qsTr("run cpp method qmlsignal")
        onClicked: qmlSignal(text)
    }

}
于 2016-01-27T19:11:23.397 回答