Click two buttons in the same and open the action of the second button using qml and Qt6

109 Views Asked by At

I have these 2 buttons and I want to click on both to open the onClick action of the second button. How can I do that to get my desired result? Maybe to use signals?

Button {
    id: btnLevel1
    x: 1016
    y: 492
    width: 554
    height: 67
    onClicked: classA.newGameWindow()
    text: "May God\nHave Mercy"
    background: Rectangle {
        color: "transparent"
    }

    font.family: "Inria Serif"
    font.pixelSize: 20
}

Text {
    id: very_hard_level
    color: "white"
    horizontalAlignment: Text.AlignHCenter
    verticalAlignment: Text.AlignTop
    wrapMode: Text.Wrap
    font.weight: Font.Normal
}

Button {
    id: btn2
    x: 58
    y: 246
    width: 188
    height: 34
    onClicked: classA.newGameWindow()
    text: qsTr("New Game")
    background: Rectangle {
        color: "transparent"
    }

    font.family: "Inria Serif"
    font.pixelSize: 26

    Text {
        id: new_Game
        color: "white"
        horizontalAlignment: Text.AlignLeft
        verticalAlignment: Text.AlignTop
        wrapMode: Text.Wrap
        font.weight: Font.Normal
    }
}

I tried to use MouseArea but didn't work and I don't know what to do

2

There are 2 best solutions below

0
iam_peter On BEST ANSWER

I still don't fully understand your use case hence the solution could be wrong.

I've used a button group to keep track of the buttons in use and also to unify the onClicked signal call. One pitfall here could be to add a AbstractButton that doesn't have the custom property activated which can be checked for.

When a button is pressed the activated property of that button is set to true, if not all buttons of the group are activated the function exits, if all buttons are activated the background of the root Window is set to yellow, which would be your entry point to call a function as far as I understood your example. Also the custom button MyButton includes an indicator Rectangle to show the activated state of that button.

That said depending on your use case there could potentially be better solutions to your problem.

import QtQuick
import QtQuick.Controls

Window {
    id: root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ButtonGroup {
        id: buttonGroup
        onClicked: function(button) {
            button.activated = true

            for (let i = 0; i < buttonGroup.buttons.length; ++i) {
                if (!buttonGroup.buttons[i].activated)
                    return
            }

            console.log("All buttons pressed")
            root.color = "yellow"
        }
    }

    component MyButton: Row {
        property alias text: button.text

        spacing: 10

        Button {
            id: button
            property bool activated: false
            ButtonGroup.group: buttonGroup
        }

        Rectangle {
            width: 20
            height: 20
            color: button.activated ? "green" : "red"
            anchors.verticalCenter: parent.verticalCenter
        }
    }

    Column {
        spacing: 10
        anchors.centerIn: parent

        MyButton { text: "Button #1" }
        MyButton { text: "Button #2" }
    }
}
2
Stephen Quan On

I agree with Jürgen Lutz. You should use functions.

Because a transition is involved, your real issue could be that of timing, of which, either a well-placed Qt.callLater() is needed or something similar, e.g.

Button {
    onClicked: {
        function1();
        function2();
        Qt.callLater( () => { classA.newGameWindow(); } );
    }
}

Another solution you may wish to consider is by using SequentialAnimation with ScriptAction to pace out your functions and page transition. You can even add PauseAnimation and PropertyAnimation:

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
    background: Rectangle { color: "#848895" }
    title: "ScriptAction Demo"
    Button {
        id: btn
        text: "abc"
        onClicked: SequentialAnimation {
            PropertyAnimation {
                target: btn // newGameWindow
                property: "opacity"
                from: 1
                to: 0.5
                duration: 500
            }
            ScriptAction { script: function1() }
            ScriptAction { script: function2() }
            PauseAnimation { duration: 100 }
            ScriptAction { script: classA.newGameWindow() }
            PropertyAnimation {
                target: btn // newGameWindow
                property: "opacity"
                from: 0.5
                to: 1
                duration: 500
            }
        }
    }
    function function1() {
        btn.text = "abc " + (new Date());
    }
    function function2() {
        btn.palette.buttonText = Qt.rgba(Math.random()/2, Math.random()/2, Math.random()/2, 1);
    }
}

You can try the latter example online!