108

私がこの信号を持っているとしましょう:

signals:
    void progressNotification(int progress);

最近、Qt の emit キーワードについて知りました。今までは、通常の関数のようにシグナルを呼び出すだけでシグナルを実行していました。したがって、代わりに:

emit progressNotification(1000 * seconds);

私は次のように書きます。

progressNotification(1000 * seconds);

それらをそのように呼び出すとうまくいくように見え、接続されているすべてのスロットが実行されるため、emit キーワードを使用すると別の動作が発生しますか、それとも単なる構文糖ですか?

4

3 に答える 3

98

emit単なる構文糖衣です。シグナルを発する関数の前処理された出力を見るemitと、ちょうどなくなっていることがわかります。

「魔法」は、moc によって生成された C++ コードを検査することで確認できる、シグナル発行関数の生成されたコードで発生します。

たとえば、fooパラメーターのない信号は、次のメンバー関数を生成します。

void W::foo()
{
    QMetaObject::activate(this, &staticMetaObject, 0, 0);
}

そして、コードemit foo();は単純に前処理されていますfoo();

emitQt/qobjectdefs.h次のように、(とにかくソースのオープンソースフレーバーで)で定義されています。

#ifndef QT_NO_EMIT
# define emit
#endif

no_keywords(定義ガードは、 QMake 構成オプションを介して、衝突する名前を持つ他のフレームワークで Qt を使用できるようにするためのものです。)

于 2012-04-15T08:15:36.500 に答える
5

18 か月後 ... @Mat の回答の下にコメントを書き始めたところ、すぐにスペースが足りなくなりました。したがって、答え。

IMOemitは、次の意味で構文糖でも単純なキーワードでもありません。

  1. コードを生成します (上記の @Mat で説明されているように)。
  2. connectこれは、メカニズムが実際に であることを認識するのsignalに役立ちます。
  3. シグナルを「より大きな」システムの一部にし、シグナルと応答 (スロット) を同期的または非同期的に実行したり、シグナルが送信された場所と方法に応じてキューに入れたりできます。これは、シグナル/スロット システムの非常に便利な機能です。

シグナル/スロット システム全体は、単純な関数呼び出しとは異なるイディオムです。それはオブザーバーパターンに由来すると思います。signalaと a の間にも大きな違いがありslotます。シグナル実装する必要はありませんが、スロットは実装する必要があります

あなたは通りを歩いていて、家が燃えているのを見ます (信号)。911 をダイヤルします (火災信号を 911 応答スロットに接続します)。信号は発射されただけで、スロットは消防署によって実装されました。不正確かもしれませんが、アイデアはわかります。OPの例を見てみましょう。

一部のバックエンド オブジェクトは、進行状況を認識しています。したがって、単純にemit progressNotification(...)信号を送ることができます。このシグナルを取得して実行するのは、実際の進行状況バーを表示するクラス次第です。しかし、ビューはこの信号にどのように接続するのでしょうか? Qt のシグナル/スロット システムへようこそ。ここで、ビュー オブジェクトとデータ計算オブジェクト (両方とも ) で構成されるマネージャー クラス (通常は一種のウィジェット) を考えるQObjectsことができますconnect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)

マネージャ クラスの設計面には立ち入りませんが、ここでシグナル/スロット システムが優れていると言えば十分でしょう。アプリケーションの非常にクリーンなアーキテクチャの設計に集中できます。常にではありませんが、多くの場合、シグナルを送信するだけでスロットを実装していることに気付きます。

シグナルメソッドを発行せずに使用/呼び出しが可能である場合、それは必然的に、そもそもその関数をシグナルとして必要としなかったことを意味します。

于 2017-01-07T22:52:11.420 に答える
-4

2番目のオプションは、関数名と関数パラメーターが何であるかを常に知っていること、および送信先のオブジェクトがその特定の関数によって認識されていることを意味します。これら 2 つのケースが常に当てはまるとは限らないため、スロットとシグナルが作成された主な理由は 2 つあります。「フードの下」のシグナルとスロットメカニズムは、接続されているすべての機能へのポインターを備えた単なるテーブルです。

また、シグナルとスロットのメカニズムの性質を非常に明確に説明しているこの pdf を見て ください。

于 2012-04-15T08:13:50.730 に答える