web-dev-qa-db-ja.com

Qtシグナルとスロット:権限

SO)での尊敬される回答と実際のQtドキュメントの間には相違があります。

私は この質問 を読みました。さらに説明が必要です。誰でも確認できます:

  • シグナルは常にprotectedであるため、クラスまたはそのサブクラスのいずれかによってのみ発行できます。これが本当かどうかはわかりません。上記の質問は、このステートメントをサポートする回答を示しています。しかし Qt docs と言う:Signals are public access functions and can be emitted from anywhere, but we recommend to only emit them from the class that defines the signal and its subclasses.それで、それはどれですか?
  • スロットは単なる機能であるため、パブリック、プライベート、または保護されています。明らかに、外部クラスwillスロットがパブリックの場合、クラスが独自の信号の1つを独自のスロットの1つに接続するかどうかを制御できます。ただし、ここでもSO情報はドキュメントとは異なります:a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class.これは、privateがシグナル/スロットメカニズムで受け入れられないことを意味しますか?
  • Public、private、protectedという単語は、signalキーワードを操作する意味がありません。
  • 発信されたシグナルはalwaysであり、他のすべてのクラスで使用できます。つまり、他のクラスは常に(シグナルを発信する許可に関係なく)そのシグナルに接続できます。
  • connect関数はクラス名をシグナルプレフィックスとして使用するため、すべてのシグナルはすべてのクラスから見ることができますが、同じ名前のシグナルを持つ2つのクラスを持つことができます(つまり、SomeClass::itsSignal
24
johnbakers
  • 信号はQt4では保護されていますが、Qt5では公開されているため、矛盾する情報が含まれています。
  • スロットは関数であり、それらを呼び出すときにpublic/protected/privateが優先されます。シグナルに接続すると、メタオブジェクトシステムはそれを無視します。
  • signalsは_public:_として定義されているため、前にそれらを追加します。プライベートリード

に:

_private:
public: //signals:
    void theSignal();
_

したがって、効果はありません。

  • すべてのクラスは任意の信号に接続できます。シグナルはその点でパブリックAPIの一部です。
  • 同一の信号署名があっても問題ありません。コンテキストは、送信者として指定されたオブジェクトによって定義されます。

古いスタイルの接続を使用する:

_Apple *Apple ... Orange* orange
connect(Apple, SIGNAL(changed()), this, SLOT(appleChanged()));
connect(orange, SIGNAL(changed()), this, SLOT(orangeChanged()));
_

シグナルはここでは文字列として(クラス名なしで)指定されていますが、Appleorangeにはそれぞれ1つのシグナルchanged()しかなく、検索はQObjectインスタンスのメタオブジェクトは、クラス(インスタンスではない)ごとに1つ存在し、衝突することはできません。

コンパイル時チェック付きのQt 5バージョン:

_connect(Apple, &Apple::changed, this, &MyReceiver::appleChanged);
_

ここでは、関数を指定する必要があるため、スコープに応じて、クラス名(およびおそらく名前空間)を指定する必要があります。あいまいな関数名は有効なC++ではなく、コンパイルできないため、ここでは安全です。

35
Frank Osterfeld

_qobjectdefs.h_(QT5.0 +)をご覧ください。そこにmocマクロが定義されています

_#     define signals public
_

ご覧のとおり、信号のヘッダーファイルで使用されるマクロはパブリックとして定義されています。明示的な状態のパブリック、プライベート、保護されたディレクティブについては、これらはシグナルセクションでは無視されます。 QTの以前のバージョン5.0では、保護された信号が定義されていました。これらは、SIGNAL()マクロを使用した接続で引き続き使用できました。

スロットマクロ

_#     define slots
_

空のマクロとして定義されているため、以下で使用できます。

_public slots:
private slots:
protected slots:
_

メソッドの可視性は直接のメソッド呼び出しに使用されるため、private/protectedを外部クラスから直接呼び出すことはできません。

A connectステートメントを使用しても、可視性とは関係なく機能します。これは意図された動作であり、moc生成コードに実装されています。

以前のバージョンのQtで正しく覚えていれば、スロットも自動的にpublicでしたが、今のところ、その参照は見つかりませんでした。

他のクラスは、Q_OBJECTマクロがクラスに指定されていて、外部クラスがわかっている(ヘッダーが含まれている)限り、外部クラスからの信号に接続できます。シグナルはクラスごとに定義されるため、異なるクラスで同じシグナルを使用することは完全に合法です。これも非常に便利です。たとえば、すべてのクラスにsendInfo(QString)シグナルがあると、覚えやすくなります。 Q_OBJECTマクロは、mocに、可視性に依存せずに信号をスロットに接続するために必要なコードを作成させます。

5
Sebastian Lange

発信されたシグナルは、他のすべてのクラスで常に利用可能です。つまり、他のクラスは常に(シグナルを発信する許可に関係なく)そのシグナルに接続できます。

Qt5では、これは必ずしも本当ではありません。シグナルは、QPrivateSignalを最後の引数として定義できます。その場合、シグナルを宣言したオブジェクトのみがシグナルに接続できます。

0