はじめに
QThreadを使っていて、
ThreadからUIを更新したい。(ログを出したい)
といった時、UIの更新を直接やるのは大抵NG。
サブスレッドからメインUIスレッドの内容を書き換えるといった流れをQtでどうするのか?
の備忘録です。(間違いあるかもですが)
シグナル、スロットを使う
Qtの場合、シグナル、スロットという仕組みがある。
これ経由して呼び出す。
Qtが拡張したメソッド呼び出しみたいなもので、いろいろ便利。
相手を知らずにブロードキャストしている emitとかがある。
emitされたシグナルを受けてスロットが動くみたいなの。
(受け側は両方知っている必要があるけど、送り側は知らなくてもOK)
シグナルスロットの接続状態
で、そのどこへ出して、どこから受けるといったことを解決するのが
connect
というもの。
これの引数に Qt::QueuedConnectionというものがある。
Qt::QueuedConnection
スレッドからきたイベント情報をキューに貯めて、良きタイミング(おそらく空いている時)に実行してくれる。
投げておけば、勝手になんかいい感じに処理してくれる。
すごい便利なやつ。管理しなくてよい。
いつ本実行されるかわからないくてもいいくらい適当なものに使える。
(UI処理だとよくある)
スレッドからくるシグナルをUIのスロットで受け取る時に、Qt::QueuedConnectionで繋いでおくことで、
スレッドをまたいで処理を行える。
接続仕方
// 色付きログ
connect(this,&HogeLogWindow::callSendLogWithColor,
this,&HogeLogWindow::sendLogWithColor,Qt::QueuedConnection);
送信
emit callSendLogWithColor("nanikaLog",textColor,textBackgroundColor);
受信
void CommandlineWindow::sendLogWithColor(QString str,QColor textColor,QColor textBackGroundColor)
{
this->ui->textEdit->setTextColor(textColor);
this->ui->textEdit->setTextBackgroundColor(textBackGroundColor);
this->ui->textEdit->append(str);
}
定義
signals:
void callSendLogWithColor(QString str,QColor textColor,QColor textBackGroundColor);
public slots:
void sendLogWithColor(QString str,QColor textColor,QColor textBackGroundColor);
Qt::QueuedConnectionの仲間
Qt::BlockingQueuedConnection てのもあって、
これは、メインで処理されるまで、サブスレッドをブロックしてしまう。
メイン側がうまく作られていればいいけど、下手に呼ぶとずっと止まってしまうので気をつけよう。
(こちらはちゃんと管理しないとやばいやつ)
処理順とかがとても大事なものなどに使うと思われる。
まとめ
Qtの中の人賢い
キーワードはQThread
Qt::QueuedConnection
以上