QML - 在事件发生时动态创建计时器

时间:2017-07-14 13:47:37

标签: javascript qt dynamic qml

我有一个ListView,其委托是一个红色按钮。当按钮的颜色发生变化时,我希望程序动态创建一个计时器(特定于该委托),在5秒后再将颜色设置为红色。然后我希望程序破坏计时器。我该怎么办?

这是我的实际代码:

ListView {
    id: myListView
    model: myListModel
    anchors.fill: parent
    anchors.leftMargin: 20; anchors.rightMargin: 20
    orientation: Qt.Vertical
    clip: true
    spacing: 8
    delegate: Button {
        id: myDelegate
        property int myDelegateIndex: index + 1
        width: 100; height: 50
        text: "Push"
        background: Rectangle {
            id: myDelegateBackground
            color: "red"
            onColorChanged: {
                myTimer.start();
            }
        }

        Timer {
            id: myTimer
            interval: 5000
            running: true
            repeat: true
            onTriggered: {
               myDelegateBackground.color = "red";
            }
        }
    }
}

非常感谢你们!

2 个答案:

答案 0 :(得分:2)

您创建一个组件

<强> SelfdestroyingTimer.qml

Timer {
    property var action // Assing a function to this, that will be executed
    running: true
    onTriggered: {
        action()
        this.destroy() // If this timer is dynamically instantitated it will be destroyed when triggered
    }
}

并且有一个功能:

function createOneShotTimer(duration, action) {
    var comp = Qt.createComponent('SelfdestroyingTimer.qml')
    comp.createObject(root,  { action: action, interval: duration })
}

或者在同一个文件中声明Component(因此每次需要实例时都不需要创建它),它看起来像这样:

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.0
import QtQuick.Dialogs 1.2

ApplicationWindow {
    id: window
    visible: true
    width: 600
    height: 600

    Component {
        id: singleShot
        Timer {
            property var action
            running: true
            onTriggered: {
                if (action) action() // To check, whether it is a function, would be better.
                this.destroy()
            }
            // This proves, it will be destroyed.
            Component.onDestruction: console.log('Timer says bye bye!')
        }
    }


    Button {
        onClicked: {
            singleShot.createObject(this, { action: function() { console.log('ACTION!!!') }, interval: 2000 })
        }
    }
}

答案 1 :(得分:0)

似乎没有必要动态创建计时器。为每个委托创建一个Timer,并通过调用restart()重用它。

见下面的例子:

ListView {
    id: myListView
    model: 20
    anchors.fill: parent
    anchors.leftMargin: 20; anchors.rightMargin: 20
    orientation: Qt.Vertical
    clip: true
    spacing: 8
    delegate: Button {
        id: myDelegate
        property int myDelegateIndex: index + 1
        width: 100; height: 50
        text: "Push"
        background: Rectangle {
            id: myDelegateBackground
            color: "red"
            onColorChanged: {
                myTimer.restart();
            }

            Timer {
                id: myTimer
                interval: 5000
                running: false
                repeat: false
                onTriggered: {
                   myDelegateBackground.color = "red";
                }
            }
        }
        onClicked: {
            background.color = "blue"
        }
    }
}

无论您选择使用何种机制,都会遇到由ListView销毁委托引起的问题,这些委托会滚出ListView的可见区域。当委托被破坏并重新创建时,它将具有原始颜色,并且计时器将处于其默认状态。

有两种方法可以解决这种情况:

  • 将委托的状态保存到委托范围之外的列表(在javascript var中)。
  • 增加Listview cacheBuffer,以便ListView在离开可见区域时不会销毁代理。