TO: 杉田さん
imudakです。ありがとうございます。助かります。
改めて検索してみたら、Qbjectのかなり上の方に定義ありますね… http://doc.qt.io/qt-4.8/qobject.html#blockSignals
ざっくりとですが、 void Model::increment() { blockSignals(true); ...(とても時間のかかる処理)... blockSignals(false); }
これで実現できそうです。早速試してみます。 ありがとうございました。
--- imudak
2016年10月12日(水) 17:49 Kenji Sugita kenji@j04.itscom.net:
杉田です。
2016/10/12 17:07、imudak imudak@gmail.comのメール:
はじめまして。imudakです。よろしくお願いします。
ずっと悩んでいることがあるのですが、 signal/slot通信で、同一シグナルの連続発行を止められないでしょうか。 想定ケースは、例えばボタン連打、周期取得処理などです。
(ボタン連打) [UI] [Model] | | |--requestInc--------->| | |-- begin: incrementの処理開始 | | |--requestInc(2回目)-->| | | | | |--requestInc(3回目)-->| | ... | |--requestInc(n回目)-->| | | (とても長い) | |-- end: increment の処理終了 | |
- 二つのクラスで間でsignal/slot通信をします。
UI: signal void requestInc(); // increment要求 Model: slot void increment(); // increment実処理
incrementは処理にとても時間がかかります(例:1分)。
このため、UIとModelを別スレッドで実行します。
QueuedConnectionでsignal/slotは接続します。
- Bの処理中もAのsignalは発行可能なので、ボタン連打などにより
requestIncはバンバン送られます。
- Modelが最初のincrementを処理したときには、signalが山のように
積みあがっいます。n個あるとすると、処理するにはn*1分かかります。
別口でUIにincrement結果を返すようななっているとすると、 連打した結果がn分後になってようやくUIに反映されます。
(周期取得処理) ボタン連打同様に、1秒ごとに値取得する周期処理などを実行すると 1分待たされる間に60個くらいsignalがたまってしまいます。
以下のように解決方法はいくつか思いつくのですが、どれもすっきりしないのです。
解1) UI側で対処: signal発行する前に止める
- Modelからslot処理終了を受けとるまで、
次の発行しない仕組みを独自に作るなど。
QObject::blockSignals(bool) で止められます。
解2) Model側で対処: slot側で受信後、実処理するか判断。
- 前のsignalを実行し終わった時間から一定時間たつまで実処理しない、など。
解3) 同期にする
- Model処理している間UIが固まります(マルチスレッド化した意味なし)
「重複したsignalのqueueがあった場合、二つ目以降は圧縮する(無視する)」 というような設定がQtにあればと思ったのですが、見当たりませんでした。 よく悩みがちな問題な気がするので、自力で作り始めてよいものかどうか…
Qtの仕組みやその周辺でスマートに解決した例などあれば、ご教示いただければ幸いです。
以上よろしくお願いします。
imudak@gmail.com _______________________________________________ Qt-users mailing list Qt-users@qt-users.jp http://qt-users.jp/mailman/listinfo/qt-users
_______________________________________________ Qt-users mailing list Qt-users@qt-users.jp http://qt-users.jp/mailman/listinfo/qt-users