如何在没有信号的情况下从C++执行QML插槽
How to execute QML slot from C++ without a signal?
我得到了一个QObject
形状的QML对象。使用->setProperty(..., ...)
,我可以更改属性,但如何在没有信号的情况下执行插槽?
目前,我在C++类中声明了一个信号:
signals:
void testSignal();
QML对象中的信号/插槽:
signal executeTestFunc(); onExecuteTestFunc: {
testAnimation.start();
}
然后我连接这两个:
QObject::connect(this, SIGNAL(testSignal()),
QmlObject, SIGNAL(executeTestFunc()));
但正如我所看到的,这并不干净:
- 事实上,这是一个奇怪的SIGNAL/SIGNAL连接
- 由于性能和长代码的原因,我不想使用SIGNAL/SLOT机制,除非迫不得已
是否有直接从QObject
执行QMLonExecuteTestFunc();
的方法?
您可以创建一个将发出信号的C++类。该信号将被QML捕获。不需要具有SIGNAL/SLOT的显式connection
。示例:
C++:
class Presenter : public QObject
{
Q_OBJECT
public:
explicit Presenter()
{
QTimer *timer = new QTimer();
timer->setInterval(500);
connect(timer, &QTimer::timeout,
this, &Presenter::timeout);
timer->start();
}
Q_SIGNAL void timeout();
};
QML:
Window {
...
Presenter {
onTimeout: {
console.log("called from c++")
}
}
}
结果:
qml: called from c++
qml: called from c++
qml: called from c++
qml: called from c++
...
@Thomenson已经给出了一个很好的答案,说明如何连接到C++的信号并在QML中对其进行操作。如果您可以从QML创建C++,那么他的解决方案就有效了,但情况可能并不总是如此。
连接元素
你可以考虑另外两种选择。首先,如果您有一个对象不是从QML创建的,而是以其他方式放入的(QML上下文,静态对象,从可调用的返回…(,则可以使用Connections
元素:
Connections {
target: theObjectWithTheSignal
onSignalName: {doSomething();}
}
这是一种灵活的方式,可以对来自您没有在QML中创建的对象,甚至是在QML其他地方创建的对象的信号做出反应。
使用JSValue回调
如果你真的坚持避免信号/插槽(尽管我不明白为什么;Qt和QML是围绕它构建的,试图避免它是在对抗框架,而不是使用它的优势(,还有另一种方法。您可以在向QML公开的C++对象上创建QJSValue
类型的属性。然后,在C++on设置中,检查设置的内容是否可调用(使用QJSValue::isCallable()
(。然后,作为要触发QML中要执行的任何内容的点,使用QJSValue::call
调用它。
在QML方面,您可以简单地分配或绑定一些可调用的东西,就像您对信号处理程序所做的那样。
反模式:QMetaObject::invokeMethod
还有另一种方式,我只将其作为对反模式的警告。可以使用Qt的内省机制从C++调用QML。您可以通过它的集合objectName
找到一个对象,并使用QMetaObject::invokeMethod调用它上的任何(可调用的(方法,读取和写入任何属性并侦听所有信号。这包括调用您在QML中定义的方法。使用它,您可以从C++操作QML不要这样做。它导致了不灵活和不可维护的代码
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 为什么catch中的代码没有被执行
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 将执行、作业和WinAPI相乘
- 对字符数组中的元素执行逐位操作
- 为什么g++在未执行的代码处标记强制转换错误
- 如何使用原子指针执行双缓冲