「Qtの基礎 - シグナルとスロット」の版間の差分

📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag…
(同じ利用者による、間の1版が非表示)
2行目: 2行目:
シグナルおよびスロットの詳細は、以下のWebサイトを参照すること。<br>
シグナルおよびスロットの詳細は、以下のWebサイトを参照すること。<br>
https://blog.qt.io/jp/2010/07/20/create-signals-and-slots-2<br>
https://blog.qt.io/jp/2010/07/20/create-signals-and-slots-2<br>
<br><br>
== connect関数 ==
==== Qt::ConnectionType ====
<code>connect</code>関数の<code>Qt::ConnectionType</code>の設定により動作が異なる。<br>
<center>
{| class="wikitable" | style="background-color:#fefefe;"
|-
! style="background-color:#66CCFF;" | 接続タイプ(定数)
! style="background-color:#66CCFF;" | 動作
|-
| Qt::AutoConnection || デフォルトの設定である。<br>SenderとReceiverが同じスレッドに存在する場合は、<code>Qt::DriectConnection</code>が使用される。<br>それ以外の場合は、<code>Qt::QueuedConnection</code>が使用される。<br><br>接続タイプはシグナルを<code>emit</code>する時に決定する。
|-
| Qt::DriectConnection || シグナルを呼び出したスレッドから対象のスロットを呼び出す。(同期呼び出し)
|-
| Qt::QueuedConnection || Receiverのスレッド上でスロット関数が呼び出される。<br>シグナルはReceiver側のキューに入れられて、Receiverのイベントルーパーからスロット関数が呼び出される。(非同期呼び出し)
|-
| Qt::BlockingQueuedConnection || 基本的な動作は、Qt::QueuedConnectionと同様であるが、<br>シグナルの呼び出した側は、受信側のスロットの実行終了を待ち合わせる。<br><br><u>多用するとデッドロックを招きやすくなる。</u><br><u>例えば、Receiver側がSender側と同じスレッドに存在する場合には、必ず、デッドロックすることに注意する。</u>
|-
| Qt::UniqueConnection || 他の接続と組み合わせてビットORで設定する接続タイプである。<br>この設定が指定されている場合、オブジェクト間のシグナルとスロット、または、シグナルとシグナルの接続の組み合わせは1度しかできなくなる。<br>2つ以上同じシグナル・スロットの組み合わせで<code>connect</code>関数を実行した場合、<code>connect</code>関数は失敗する。<br><br>この設定は、Qt 4.6で追加された。
|}
</center>
<br>
==== connect関数 ====
<code>connect</code>関数は大きく分けて、2種類、細かく分けて4種類の種類が存在する。<br>
<center>
{| class="wikitable" | style="background-color:#fefefe;"
|-
! style="background-color:#66CCFF;" | connect関数のシンタックス
! style="background-color:#66CCFF;" | スタイルの呼称
|-
| Stringベース || Qt 4スタイル
|-
| rowspan=3 | Functorベース
| Qt 5スタイル
|-
| Lambdaスタイル 1
|-
| Lambdaスタイル 2
|}
</center>
<br>
<syntaxhighlight lang="c++">
// Qt 4スタイルのconnect関数の形式
QMetaObject::Connection QObject::connect(Senderのポインタ, SIGNAL(シグナルの関数名(引数の型, ...)), Receiverのポインタ, SLOT(スロットの関数名(引数の型, ...)), Qt::ConnectionType type = Qt::AutoConnection)
// 例.
connect(sender, SIGNAL(value3Changed(int)), receiver, SLOT(setValue3(int)));
// Qt 5スタイルのconnect関数の形式
QMetaObject::Connection QObject::connect(Senderのポインタ, &シグナルのクラス名::シグナルの関数名, Receiverのポインタ, &スロットのクラス名::スロットの関数名, Qt::ConnectionType type = Qt::AutoConnection)
// 例.
connect(sender, &Sender::value3Changed, receiver, &Receiver::setValue3);
</syntaxhighlight>
<br>
<code>connect</code>関数の第2引数と第4引数において、Qt 4スタイルでは<code>SIGNAL</code>、<code>SLOT</code>というマクロを使用する。<br>
このマクロは、Qt側で文字列(const char *signalのように)に変換される。<br>
Qt 5スタイルと異なる点を、以下に示す。<br>
* マクロの有無
* クラス名を記述するかどうか
* 仮引数を明示的に記述するかどうか
<br>
<syntaxhighlight lang="c++">
// Lambdaスタイル 1のconnect関数の形式
QMetaObject::Connection connect(Senderのポインタ, &Senderのクラス名::シグナルの関数名, [=]() { 処理1; 処理2; ...; });
// 例.
connect(sender, &Sender::valueChanged, [=]() { qDebug() << "Lambda Style1 signal received."; });
// Lambdaスタイル 2のconnect関数の形式
QMetaObject::Connection connect(Senderのポインタ, &Senderのクラス名::シグナルの関数名, コンテキストオブジェクト, [=]() { 処理1; 処理2; ...; }, Qt::QueuedConnection);
// 例.
connect(sender, &MyObject1::valueChanged, this, [=]() { qDebug() << "Lambda Style2 signal received."; }, Qt::QueuedConnection);
</syntaxhighlight>
<br>
Lambda形式は、Receiverのスロット関数を作成しなくてよいため、シグナルが発生しているかどうかログを出力する時に便利である。<br>
<br>
Lambdaスタイル 1は、引数に<code>Qt::ConnectionType</code>が無い。<br>
また、<code>Qt::ConnectionType</code>が<code>Qt::DirectConnection</code>固定となる。<br>
つまり、SenderとReceiverが同一スレッドで動作することが前提となる。<br>
<code>send</code>関数により、Senderを取得することもできない。<br>
<br>
Lambdaスタイル 2は、Qt 5.2で追加されたシンタックスである。<br>
Lambdaスタイル 1と比較すると、第3引数にコンテキストが追加されて、第5引数に<code>Qt::ConnectionType</code>が追加されている。<br>
<code>Qt::ConnectionType</code>が指定できるため、<code>Qt::DirectConnection</code>以外の動作も可能である。<br>
また、<code>QObject::sender</code>関数も使用できる。<br>
<br>
上記のLambdaスタイル 1およびLambdaスタイル 2の例では、ラムダ式に<code>キャプチャ式 [=]</code>を使用しているが、<code>キャプチャ式 [=]</code>以外のキャプチャ記法も使用できる。<br>
<br>
<center>
{| class="wikitable" | style="background-color:#fefefe;"
|+  StringベースとFunctorベースの比較
|-
! style="background-color:#66CCFF;width:50%;" | 
! style="background-color:#66CCFF;width:25%;" | Stringベース
! style="background-color:#66CCFF;width:25%;" | Functorベース
|-
| 型チェックのタイミング
| style="text-align: center;" | 実行時
| style="text-align: center;" | コンパイル時
|-
| 暗黙の型変換
| style="text-align: center;" | 不可
| style="text-align: center;" | 可能
|-
| シグナルをラムダ式で接続できる
| style="text-align: center;" | 不可
| style="text-align: center;" | 可能
|-
| シグナルより多くの引数を持つスロットに<br>シグナルを接続できる
| style="text-align: center;" | 可能
| style="text-align: center;" | 不可
|-
| QMLに接続できる
| style="text-align: center;" | 可能
| style="text-align: center;" | 可能
|}
</center>
<br><br>
<br><br>


146行目: 268行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>
{{#seo:
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux
|image=/resources/assets/MochiuLogo_Single_Blue.png
}}


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]