Ste*_*nov 4 qt signals-slots qml observer-pattern qtquick2
考虑以下JS代码:
function handleSig() {
emitter.someSig.disconnect(handleSig);
// do some work here
}
emitter.someSig.connect(handleSig);
Run Code Online (Sandbox Code Playgroud)
是否可以在没有显式断开连接和命名函数的情况下进行编写?
理想情况下,我想要这样的东西:
emitter.someSig.connect(
function() {
// do some work here
},
Qt.SingleShotConnection
);
Run Code Online (Sandbox Code Playgroud)
几乎重复:第一次发出信号后自动断开连接 -但是这个问题与Python有关,而我的问题与QML和C ++有关。
我在这里找到了C ++的答案,尽管有点不雅致:
https://forum.qt.io/topic/67272/how-to-create-a-single-shot-one-time-connection-to-a-lambda/2
该链接中的代码:
QMetaObject::Connection * const connection = new QMetaObject::Connection;
*connection = connect(_textFadeOutAnimation, &QPropertyAnimation::finished, [this, text, connection](){
QObject::disconnect(*connection);
delete connection;
});
Run Code Online (Sandbox Code Playgroud)
我仍在寻求更好的C ++答案和QML答案。
您可以创建一个小的辅助函数,该函数可以为您断开连接,例如:
function connectOnce(sig, slot) {
var f = function() {
slot.apply(this, arguments)
sig.disconnect(f)
}
sig.connect(f)
}
Run Code Online (Sandbox Code Playgroud)
作为用法的演示:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: myWindow
visible: true
width: 600
height: 600
color: 'white'
signal action(string name)
function slot(name) {
console.log(name)
}
Button {
text: 'connect'
onClicked: {
connectOnce(action, slot)
}
}
Button {
y: 80
text: 'action'
onClicked: {
action('test')
}
}
function connectOnce(sig, slot) {
var f = function() {
slot.apply(this, arguments)
sig.disconnect(f)
}
sig.connect(f)
}
}
Run Code Online (Sandbox Code Playgroud)
上面的两个按钮即可连接slot,并slot2在单次模式的信号action。Button 动作将触发信号action,该信号将执行与连接的插槽相同的次数。然后它们将立即断开连接。
您可以将函数connectOnce放入库中,以在任何需要的地方使用。
此解决方案很容易扩展为更通用的形式,该形式n通过在闭包中引入一个计数器来连接要执行的函数的时间:
function connectN(sig, slot, n) {
if (n <= 0) return
var f = function() {
slot.apply(this, arguments)
n--
if (n <= 0) sig.disconnect(f)
}
sig.connect(f)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2243 次 |
| 最近记录: |