响应 QML 按钮调用 C++ 代码的最正式方法是什么?
What is the most formal way to invoke C++ code in response to a QML button?
使用 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.qrc
中的QML文件:
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")
}
}
我知道 this 是一个可能的答案,但将按钮挂接到代码看起来是一种非常复杂的方法!如果这是使用 Qt 5.5 和 QML 的正式方式,那么这应该就是答案。
如您在 documentation 中所见,您有多种选择:
- class 可以注册为可实例化的 QML 类型。这是@BaCaRoZzo提出的选项
- class 可以注册为单例类型
- class 的实例可以作为上下文 属性 或上下文对象
嵌入到 QML 代码中
- Qt QML 模块还提供了从 C++ 代码执行反向操作和操作 QML 对象的方法。这是@hyde
提出的方案
对于您的情况,我更喜欢最后一个选项,因为它需要的代码行数更少。
示例:
main.cpp
// 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)
}
}
myclass.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
我做了一个例子来展示@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++的头文件class:
// 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)
}
}
使用 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.qrc
中的QML文件:
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")
}
}
我知道 this 是一个可能的答案,但将按钮挂接到代码看起来是一种非常复杂的方法!如果这是使用 Qt 5.5 和 QML 的正式方式,那么这应该就是答案。
如您在 documentation 中所见,您有多种选择:
- class 可以注册为可实例化的 QML 类型。这是@BaCaRoZzo提出的选项
- class 可以注册为单例类型
- class 的实例可以作为上下文 属性 或上下文对象 嵌入到 QML 代码中
- Qt QML 模块还提供了从 C++ 代码执行反向操作和操作 QML 对象的方法。这是@hyde 提出的方案
对于您的情况,我更喜欢最后一个选项,因为它需要的代码行数更少。
示例:
main.cpp
// 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)
}
}
myclass.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
我做了一个例子来展示@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++的头文件class:
// 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)
}
}