问题描述
我有一个 C++服务",我想向 QML 公开它的接口.我正在尝试使用 QQmlContext
的 setContextProperty
将对象链接到 QML 并从 QML Connections
块.
I have what I'm calling a C++ "service" who's interface I want to expose to QML. I'm trying to use QQmlContext
's setContextProperty
to link the object into the QML and connect to it from a QML Connections
block.
QML 不会像以前那样在我没有在 QML 上下文中注册服务时抱怨引用错误:
QML isn't complaining with a reference error as it did previously when I hadn't registered the service in the QML context:
qrc:/main.qml:13: ReferenceError: service is not defined
所以,QML 现在似乎找到了 service
对象,但是 QML 插槽 javascript 函数没有被调用.我在 Qt Creator 中看到了这一点:
So, QML seems to find the service
object now, however the QML slot javascript function is not getting invoked. I see this in Qt Creator:
Debugging starts
QML debugging is enabled. Only use this in a safe environment.
QML Debugger: Waiting for connection on port 62301...
Calling the clbk signal
Debugging has finished
每个 console.log("In onClbk");
应该有一个 In onClbk
消息;我知道我可以使用 QMetaObject::invokeMethod
调用 QML 对象的直接函数,但我试图通过使用信号和插槽来降低耦合.
There should be an In onClbk
message per console.log("In onClbk");
I know that I can use QMetaObject::invokeMethod
to invoke a QML object's function directly, but I am trying to have a little looser coupling through the use of signals and slots.
如果可能,我想避免创建 QQuickItem
并在 QML 中实例化服务.
I would like to avoid creating a QQuickItem
and instantiating the service in the QML, if at all possible.
不幸的是,样板代码很多,这是我的SSCCE.
这是通过 Qt Creator 创建的所有项目目录的 zip 文件5.4.
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
auto rc = engine.rootContext();
auto service = new Service();
engine.rootContext()->setContextProperty(QStringLiteral("service"), service);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
// invoke the trigger arbitrarily
QTimer *timer = new QTimer();
timer->setSingleShot(true);
QObject::connect(timer, SIGNAL(timeout()), service, SLOT(trigger_clbk()));
timer->start(4000);
return app.exec();
}
service.h
class Service : public QQuickItem {
Q_OBJECT
public:
virtual ~Service(){}
signals:
void clbk();
public slots:
void trigger_clbk() {
qDebug()<<"Calling the clbk signal";
clbk();
}
};
main.qml
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
// subscribe to a signal
Connections {
target: service
onClbk: function(){
console.log("In onClbk");
}
}
}
}
Main.ui.qml
import QtQuick 2.3
Rectangle {
property alias mouseArea: mouseArea
width: 360
height: 360
MouseArea {
id: mouseArea
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: "Hello World"
}
}
推荐答案
您正在尝试将一个 JS 函数分配给 cblk
信号处理程序,它不会作为信号处理程序工作 是 处理信号的函数.所以 Connections
块应该是:
You're trying to assign a JS function to the cblk
signal handler, that's not going to work as the signal handler is the function that handles the signal. So the Connections
block should read:
Connections {
target: service
onClbk: {
console.log("In onClbk");
}
}
这篇关于如何从 QML 收听 C++ 信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!