2017-07-10 14 views
1

を一度だけスロットを呼び出した後、自動切断それら:接続信号が、これは、コードを考えてみましょうJS

function handleSig() { 
    emitter.someSig.disconnect(handleSig); 
    // do some work here 
} 

emitter.someSig.connect(handleSig); 

それが明示的に切断し、指定された関数せずに書き込むことができますか?

理想的には、私はこのような何か希望:近重複

emitter.someSig.connect(
    function() { 
     // do some work here 
    }, 
    Qt.SingleShotConnection 
); 

Automatically disconnect after first signal emissionを - しかし、その質問は、Pythonについてですと私はQMLとC++についてです。

+0

何の問題切断 'を呼び出すために() '? – folibis

+0

@folibis:1.それから、 'handleSig'という名前は3倍になります。2.読みにくいです。3.ハンドラーを' connect'呼び出しの中で定義することはできません。 –

答えて

2

あなたは、このようなように、あなたのための切断を行い、小さなヘルパー関数を作成することができます。使用方法のデモンストレーションとして

function connectOnce(sig, slot) { 
    var f = function() { 
     slot.apply(this, arguments) 
     sig.disconnect(f) 
    } 
    sig.connect(f) 
} 

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) 
    } 
} 

を上位2つのボタンslotを接続し、シングルショットモードのslot2を信号actionに変換します。 ボタンアクションは、接続されている回数だけスロットを実行する信号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) 
} 
+0

なぜ私はこれを考えなかったのですか? :) –

0

それは少し無粋だけれども、私は、ここでは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; 
}); 

、私はまだ良いC++答えを差し出しています、 QMLの回答に使用します。