【Qt】QSignalMapperは まいそうされます。
画像のような複数のUIの操作に応じて一つのUIを更新する処理は QSignalMapper が担ってきました。
しかし Qt5 では QSignalMapper は非推奨とされ、 ラムダ式 への置き換えが推奨されます。
そこで、実際にどのように置き換えていくかをここに記録します。
従来の QSignalMapper を用いた手法
// legacy style signal mapping mapper = new QSignalMapper(this); QVector<QPushButton *> foobarButtons({ ui.fooButton, ui.barButton, ui.foobarButton, }); for (auto const &button : foobarButtons) { connect(button, SIGNAL(clicked()), mapper, SLOT(map())); mapper->setMapping(button, button->text()); } connect(mapper, SIGNAL(mapped(QString)), this, SLOT(foobarLabelUpdate(QString)));
処理の流れは次の通りです:
- QSignalMapper を作成する。
- sender(
button
) から QSignalMapper へ connect をする。 QSignalMapper::map()
が実行されるとき、 QSignalMapper から送出する内容を登録する。QSignalMapper::mappped()
から送出される内容を受け取る slot (foobarLabelUpdate
) へ connect する。
前提として必要なことは2つ、 QSignalMapper のインスタンス と 該当の操作に対応できるSlot そして、くじけない心です。
- 出版社/メーカー: アトラス
- 発売日: 2008/02/21
- メディア: Video Game
- 購入: 5人 クリック: 124回
- この商品を含むブログ (242件) を見る
ラムダ式を用いた手法
// qt5 style signal mapping QVector<QPushButton *> fizzbuzzButtons({ ui.fizzButton, ui.buzzButton, ui.fizzbuzzButton, }); for (auto const &button : fizzbuzzButtons) { auto const &text = button->text(); connect(button, &QPushButton::clicked, [=] { ui.fizzbuzzLabel->setText(text); }); }
処理の流れは次の通りです:
- sender(
button
) からラムダ式へ connect をする。
もう少し言うと、[=]
ではじまるラムダ式なので送出していた内容を変数text
に格納するという準備をしています。
これは比較のためにQStringで揃えているだけですので、buttonそのものを渡すことでより簡潔に書けます。
for (auto const &button : fizzbuzzButtons) { connect(button, &QPushButton::clicked, [=] { ui.fizzbuzzLabel->setText(button->text()); }); }
非常にシンプルになりました。 これなら気軽に書いていけますね。