📢 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… |
|||
| (同じ利用者による、間の2版が非表示) | |||
| 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> | ||
| 126行目: | 248行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
== Qt Designerで設定したシグナルおよびスロット == | |||
Qt Designerで設定したシグナルおよびスロットは、<code>connect</code>関数を使用せずに呼び出すことができる。<br> | |||
<br> | |||
ソースコード上で<code>connect</code>関数を使用せずにスロット関数が呼び出される理由を以下に示す。<br> | |||
まず、<code>QWidget</code>クラスや<code>QMainWindow</code>クラス等を継承した派生クラスにおいて、コンストラクタに自動生成されるソースコードで、以下の記述がある。<br> | |||
ui->setupUi(this); | |||
<br> | |||
次に、<code>setupUi</code>メソッドの定義の最後に、以下の記述がある。<br> | |||
以下に示す<code>QMetaObject::connectSlotsByName</code>メソッドは、オブジェクト(引数)が持つ全てのスロットに対して、<br> | |||
<code>on_<子オブジェクト名>_<子オブジェクトのシグナル名></code>を満たすスロット名の存在を確認する。<br> | |||
<syntaxhighlight lang="c++"> | |||
void setupUi(QMainWindow *MainWindow) | |||
{ | |||
// ...略 | |||
QMetaObject::connectSlotsByName(MainWindow); | |||
} | |||
</syntaxhighlight> | |||
<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]] | ||