言語切り替え処理中に表示更新は可能でしょうか?
-
組み込みLinux環境でQt5.3(QML)を使用したメニューシステムを作成中なのですが、
500語ほどの翻訳語が存在する状態で、languageChangedシグナルをemitすると、
2秒程度、すべての画面更新が止まってしまいます。(環境の処理速度にもよるのでしょうが・・・)
このとき”Waiting”表示を行って、砂時計的なアニメーションを表示させたいと思っているのですが、
可能でしょうか?
languageChangedシグナルがどの処理につながっているのか調べてみましたが、
Qt5.3のソース内で、幾つかconnectされていて、Qtシステム側で色々処理されているようでした。 -
言語の切替時の対応ですが http://qt-project.org/wiki/How_to_do_dynamic_translation_in_QML をベースにしたものと考えて良いでしょうか。
この処理はメインスレッド(UIスレッド)で実行されるため、基本的にはその最中のアニメーションも停止してしまうと思います。
ただし、Animator 系のエレメント( http://qt-project.org/doc/qt-5/qml-qtquick-animator.html )を用いてアニメーションを作成した場合かつ、スレッドレンダリングモード( http://qt-project.org/doc/qt-5/qtquick-visualcanvas-scenegraph.html#threaded-render-loop )の場合はメインスレッド停止中もアニメーションが動作します。Animator 系クラスは数が少ないので注意してください。
- OpacityAnimator
- RotationAnimator
- ScaleAnimator
- UniformAnimator
- XAnimator
- YAnimator
@Item {
anchors.fill: parentRectangle { id: indicator width: 100; height: 100 anchors.centerIn: parent color: "red" } ScaleAnimator { id: animator target: indicator from: 1.0; to: 2.0 duration: 1000 loops: Animator.Infinite running: true } Button { text: qsTr("Click"); anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom onClicked: { var d1 = new Date().getTime(); var d2 = new Date().getTime(); while( d2 < d1+1000*3 ){ d2 = new Date().getTime(); } } }
}@
Qt 5.3 on Linux/X11 で QML_FORCE_THREADED_RENDERER=1 で上記のコードが停止せずにアニメーションすることを確認しました。組み込み Linux であれば環境変数無しでもうまく動くと思います。
( なお、Animator の running が true になってから一度イベントループに戻らないとアニメーションが開始されません。)それから、もちろんチップなどによりますが、2秒は少し長い気がします。原因としては
- languageChanged シグナルが複数回送出されている
- その時点で表示していない画面などのインスタンスが生きており、そちらの画面の文字列も変更している
- onTextChanged など文字列の変更に伴うバインディングやシグナルハンドリングが多い
などがあると思います。見直されるのであれば参考に。
-
Qt5.3、組み込みLinux環境で、ご教示頂いたAnimatorクラスを試してみました。
環境変数QML_FORCE_THREADED_RENDERERは、
よくわからなかったため、とりあえずスルーしましたが、
QMLでAnimatorを使用することで、
言語切り替え処理中でもAnimatorで指定した描画が
動作することを確認できました。(ありがとうございます)Animatorクラスですが、QMLのImportは、QtQuick 2.2、が必要なのですね。
そこで、少しつまづいてしまったので、一応補足まで。