首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >qml属性更新是如何组织的?

qml属性更新是如何组织的?
EN

Stack Overflow用户
提问于 2016-06-23 14:23:01
回答 1查看 124关注 0票数 0

我正在尝试在UI项目中使用信号。我想要一个按钮来启动一些进程。当我这么做的时候,我意识到我不明白发生了什么,所以我写了下面的代码,试图指出正在发生的事情。

运行时,main.qml创建一些彩色框作为控件,一些白色框用于输出(由SubOne.qml生成)。

如果单击绿色框,它会发出“广播”信号,每个白框都连接到该信号。

在“广播”上,每个白框调用其功能栏。

酒吧开始循环。在循环结束时,它会打印迭代次数,并更改text属性以显示相同的次数。

第一和第三白框执行1循环,但第二框执行足够的循环以导致明显的延迟。

好吧,一切看起来都很好。正如预期的那样,这三个函数条被依次调用,并按顺序输出它们的打印。但是,我发现文本属性并没有按顺序更新。相反,所有的条形图都完成了,然后所有三个文本属性一起更新。

换句话说,在SubOne.qml中,第17行直到所有循环完成后才生效,但是第18行在每个循环完成后才生效。

有人能告诉我发生了什么事吗?qml是否在做一些事情来优化对显示的写入?如果是的话,它能被控制吗?

主要是如何使打印和文本更新在每个循环退出后一起进行。

谢谢你的帮助。

//qml.main

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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})
}

值得注意的是,sendMessage在SubOne.qml的第26行没有在SubOne的第14行由onMessage处理,而是在script.js的第1行由WorkerScript.onMessage处理,而script.js的第7行的WorkerScript.sendMessage则在第14行的SubOne.qml文件中被处理。此外,发送给新线程的消息只有一个参数,因此为了发送nameVal和loopVal,我将它们放在一个对象中,在SubOne.qml的第26行创建

也许这是显而易见的,但我一时糊涂了;)

有趣的是,如果在循环期间按下'red‘,主线程就会立即退出,但是第二个线程会完成它首先做的事情。

希望这能帮上忙。

感谢BaCaRoZzo和Kuba。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-23 15:05:39

QML在这里没有做什么--你做了,因为你阻塞了事件循环。当您的代码运行时,事件循环不存在,而且QML无法执行任何显示更新。必须将控制权交回事件循环,以使显示更新。这与基于小部件的UI没有什么不同。你在那里也会有同样的行为。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37994419

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档