LiGhT_WoLF LiGhT_WoLF - 2 months ago 25
C++ Question

Call C++ function after QML animation finishes

I need to call a C++ class method with parameters from UI after animation of SwipeView ends.

main.ui

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

SwipeView {
id: swipeView
anchors.fill: parent

Page1 {
id: page1
}

Page2{
id: page2
}
}

XOR {
id: xor
onXorEnded: {
//swipeView.setCurrentIndex(0)
}
onQChanged: {
page2.bar.value = xor.getq()
}
}


}

Page1Form.ui.qml

Page1Form {



kpButton.onClicked: {
kpDialog.visible = true
}

xorButton.onClicked: {
swipeView.setCurrentIndex(1)
xor.crypt(file_path.text, key_path.text, out_path.text)
}

fpButton.onClicked:{
fpDialog.visible = true
}


FileDialog {
id: fpDialog
onAccepted: {
file_path.text = fpDialog.fileUrl
}
}

FileDialog {
id: kpDialog
onAccepted: {
key_path.text = kpDialog.fileUrl
}
}
}


It seems like in xorButton.onClicked xoring starting before animation of swipe view ends. How it works now: Imgur

Answer

As a workaround you can bind your action to index changing:

xorButton.onClicked: {
    swipeView.setCurrentIndex(1)
}


SwipeView {
    id: swipeView
    onCurrentItemChanged: {
        if(currentIndex == 1)
            xor.crypt(file_path.text, key_path.text, out_path.text)
    }
}

But anyway, that fires not at end of animation.

As another workaround you can use StackView. It has more properties to control the animation. Another advantage of this control is that user cannot swipe it when you don't expect it. In your case an user just can swipe that. One more advantage is that page doesn't take memory when you don't need it.

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0


Window {
    visible: true
    width: 800
    height: 800
    StackView {
        id: view
        anchors.fill: parent
        initialItem: page1
        onBusyChanged: {
            if(!busy && currentItem.objectName == "page2")
                currentItem.run();
        }
    }
    Component {
        id: page1
        Rectangle {
            color: "green"
            objectName: "page1"
            Button {
                anchors.centerIn: parent
                text: "swipe me"
                onClicked:
                    view.push(page2)
            }
        }
    }

    Component {
        id: page2
        Rectangle {
            color: "yellow"
            objectName: "page2"
            function run() { sign.visible = true; }

            Rectangle {
                id: sign
                anchors.centerIn: parent
                width: 100
                height: 100
                radius: 50
                color: "red"
                visible: false
            }
        }
    }

}