私のUIプロジェクトで信号を使って実験しています。私はボタンをいくつかのプロセスを開始したい。私がこれをやっている間、私は何が起こっているのか分からなかったことに気がついたので、私は起こっていたことをピンポイントで調べるために以下のコードを書きました。qmlプロパティの更新はどのように整理されていますか?
実行すると、main.qmlはいくつかの色付きボックスをコントロールとして作成し、出力用に白いボックス(SubOne.qmlから作成)を作成します。
緑色のボックスをクリックすると、信号「ブロードキャスト」が放射され、各白いボックスがその信号に接続されます。
「ブロードキャスト」では、各白いボックスがその機能バーを呼び出します。
バーがループを開始します。ループの終わりには反復回数が出力され、テキストプロパティは同じ数に変更されます。
第1と第3の白いボックスは1ループですが、第2のボックスは目立つ遅延を引き起こすのに十分なループを行います。
すべては問題ありません。予想どおり、3つのファンクションバーは順次呼び出され、順番に出力されます。しかし、私は、テキストプロパティが順番に更新されないことに驚いていました。すべてのバーが終了し、3つのテキストプロパティがすべて一緒に更新されます。
つまり、SubOne.qmlでは、17行目はALLループが完了するまで有効になりませんが、18行目はEACHループが完了すると有効になります。
何が起こっているのか教えていただけますか? qmlはディスプレイへの書き込みを最適化するために何かしていますか?そうであれば、それを制御することができます。
主に、各ループが終了した後、印刷とテキストの更新を一緒に行うことができます。
ありがとうございました。ここで
//qml.main
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
visible: true
Rectangle {
Rectangle {
x: 50
y: 50
width: 50
height: 50
color: "green"
Text {
text: "Start"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
MouseArea {
id: start
signal broadcast()
anchors.fill: parent
onClicked: broadcast();
}
}
Rectangle {
function set() {
first.thisText = "---";
second.thisText = "---";
third.thisText = "---";
}
id: reset
x: 110
y: 50
width: 50
height: 50
color: "yellow"
Text {
text: "Reset"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
MouseArea {
anchors.fill: parent
onClicked: reset.set();
}
}
Rectangle {
id: exit
x: 170
y: 50
width: 50
height: 50
color: "red"
Text {
text: "Exit"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
MouseArea {
anchors.fill: parent
onClicked: Qt.quit();
}
}
}
SubOne {
id: third
thisName: "third"
x: 50
y: 110
loop: 1
}
SubOne {
id: second
thisName: "second"
x: 50
y: 170
loop: 100000000
}
SubOne {
id: first
thisName: "first"
x: 50
y: 230
loop: 1
}
}
//SubOne.qml
import QtQuick 2.0
Rectangle {
id: rectangle1
property string thisName: ""
property string thisText: "nothing yet"
property int loop: 1
height:50
width:170
function bar() {
print("looping " + thisName + " with: " + loop);
for (var counter=0; counter<loop; counter+=1){
//do nothing much
}
thisText = counter;
print("looped " + thisName + " to: " + counter);
}
Text {
text: thisText
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
Connections {
target: start
onBroadcast: bar()
}
}
示唆したように、WorkerScriptを使用して、新しいコードです。
//SubOne.qml
import QtQuick 2.0
Rectangle {
id: rectangle1
property string thisName: ""
property string thisText: "nothing yet"
property int loop: 1
height:50
width:170
WorkerScript {
id: myWorker
source: "script.js"
onMessage: thisText = messageObject.reply
}
Text {
text: thisText
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
Connections {
target: start
onBroadcast: {
myWorker.sendMessage({'loopVal':loop, 'nameVal':thisName});
}
}
}
//script.js
WorkerScript.onMessage = function(obj) {
print("looping " + obj.nameVal + " to: " + obj.loopVal);
for (var counter=0; counter<obj.loopVal; counter+=1){
//do nothing much
}
print("finished " + obj.nameVal + " at: " + counter);
WorkerScript.sendMessage({ 'reply': counter})
}
SubOne.qmlのライン26上のsendMessageがでのonMessageによって処理されないことは注目に値しますSubOneの14行目はscript.jsの1行目のWorkerScript.onMessageによって処理され、同様にscript.jsの7行目のWorkerScript.sendMessageは14行目のSubOne.qmlファイルで処理されます。また、新しいスレッドに送られたメッセージは1つのパラメータだけを取得するので、nameValとloopValを送信するにはオブジェクトには、ラインにインラインを作成SubOne.qml
の26たぶんそれは明白ですが、それはしばらくの間、私を混同し、
その興味深いあなたがループ中に「赤」を押した場合には、メイン)スレッドはすぐに終了しますが、2番目のスレッドは最初に何を行ったのかを完了します。
これは誰かを助けることを望みます。
そして、BaCaRoZzoとKuba Oberのおかげです。
Kuba Oberが指摘するように、あなたはメインスレッドをブロックしています。 GUIは、まったく同じスレッドで更新されます。問題のコードを作業スレッドにオフロードする必要があります。可能なアプローチについては、['WorkerScript'](http://doc.qt.io/qt-5/qml-workerscript.html#details)を見てみてください。 – BaCaRoZzo
ああ、もちろん。私はそれを考えていたはずです。私はそれをWorkerScriptを使用するよう書き直し、できるだけ早く他の人のために投稿します。あなたのおかげで両方。 –