Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QML onClicked no activity



  • I have a QML section:

                Image{
                    id: iconLocal
                    anchors.right: parent.right //put this on the right side
                    source: "images/fake assets/arrow_right_green.png"
                    width: 64; height: 64
                    opacity: 0.7
    
                    MouseArea {
                        anchors.fill: parent
                        hoverEnabled: true
                        acceptedButtons: Qt.LeftButton
    
                        onClicked: {
    console.info("A here!");
                            //connectionSelector.ipChosen("localhost", d.keyString);
    console.info("B here!");
                        }
                        onEntered: iconLocal.opacity = 1.0
                        onExited: iconLocal.opacity = 0.7
                    }
    

    The image is placed in the correct location. I can see that when the mouse is moved onto the image and out the onEntered and onExited sections are working, but I get no clicked event. I've tried setting a breakpoint in the onClicked handler and I never see either the console messages or any activity on the breakpoint.

    I've also tried:

                Image{
                    id: iconLocal
                    anchors.right: parent.right //put this on the right side
                    source: "images/fake assets/arrow_right_green.png"
                    width: 64; height: 64
                    opacity: 0.7
                }
                MouseArea {
                    anchors.fill: parent
                    hoverEnabled: true
                    acceptedButtons: Qt.LeftButton
    
                    onClicked: {
    console.info("A here!");
                        //connectionSelector.ipChosen("localhost", d.keyString);
    console.info("B here!");
                    }
                    onEntered: iconLocal.opacity = 1.0
                    onExited: iconLocal.opacity = 0.7
                }
    

    What could be wrong?


  • Moderators

    @SPlatten
    works perfectly fine in this small example (5.12.6, macOS)

    import QtQuick 2.12
    import QtQuick.Window 2.0
    import QtQuick.Controls 2.12
    
    import Qt.labs.settings 1.0
    
    Window {
        id: window
    
        width: 120
        height: 60
    
        visible: true
    
        Item {
            anchors.fill: parent
            focus: true
    
            Image{
                            id: iconLocal
                            anchors.right: parent.right //put this on the right side
                            source: "https://apod.nasa.gov/apod/image/1907/SpotlessSunIss_Colacurcio_960.jpg"
                            width: 64; height: 64
                            opacity: 0.7
                        }
                        MouseArea {
                            anchors.fill: parent
                            hoverEnabled: true
                            acceptedButtons: Qt.LeftButton
    
                            onClicked: {
            console.info("A here!");
                                //connectionSelector.ipChosen("localhost", d.keyString);
            console.info("B here!");
                            }
                            onEntered: iconLocal.opacity = 1.0
                            onExited: iconLocal.opacity = 0.7
                        }
        }
    }
    
    

    seems like its the surrounding code. Can you show more?



  • @J-Hilk thank you, this is the entire QML file, there are other references, if you need to see just ask:

    ////////////////////////////////////////////////////////////////////
    // ConnectionSelector.qml
    // Allows user to specify connecting to localhost or to a
    // manually entered ip address. This is not normally shown
    // as mostly the UI will be run using the auto-connect option
    // by specifying the IP at the command line.
    //
    // Note that unlike every other screen, this is more likely to
    // be mouse-driven than touch-driven.
    //
    import QtQuick 2.6
    import "Utils.js" as Utils
    
    Rectangle {
        id: connectionSelector
    
        //"private" variables
        QtObject {
            id:d
            property string ipString: ""
            property string keyString: ""
            property color textColour: "#ffffff"
            property string lastIpAddress: ""
        }
    
        Component.onCompleted: {
            initialiseIPandKey()
        }
    
        //loads previously-saved ip/key information from the database
        function initialiseIPandKey(){
            Utils.initialiseStorage("UI");
            var lastIpAddress = Utils.setting("lastIpAddress");
            var lastAccessKey = Utils.setting("lastAccessKey");
            if (lastIpAddress === undefined) {
                Utils.setSetting("lastIpAddress", "192.168.10.254");
            }
            if (lastAccessKey === undefined) {
                Utils.setSetting("lastAccessKey", "1.2.3.4");
            }
            lastIpAddress = Utils.setting("lastIpAddress");
            lastAccessKey = Utils.setting("lastAccessKey");
    
            d.lastIpAddress = lastIpAddress
            d.keyString = lastAccessKey
        }
    
        //save the ip for later so it's known when we reload
        function saveCustomIp(ip) {
            Utils.setSetting("lastIpAddress", ip)
        }
    
        //actually makes the connection happen by calling into the connection manager
        function ipChosen(ip, keyString) {
            connectionManagerModel.setConnectionAttributes(ip, keyString)
            connectionManagerModel.initialiseConnection()
        }
    
        //static background image
        Image {
            anchors.fill: parent
            id: backgroundImage
            source: "images/STARTUP_SHUTDOWN/startup_background.jpg"
        }
    
    
        //displays connection-state-appropriate text (see state machine for content)
        Text {
            id: licenceText
            anchors { top: parent.top; left: parent.left; leftMargin: 10; topMargin: 10 }
            font.pointSize: 10
            color:  userAccessModel.licenceExpired ? Utils.expiredLicenceColour() : Utils.splashScreenTextColor()
            text: (userAccessModel.isAuthenticated || userAccessModel.licenceExpired)
                    ? "Licenced to " +userAccessModel.authenticatedUser + ". Expires: " + userAccessModel.licenceExpiryDate
                    : "Not licenced for remote connections"
        }
    
        //two rows of connection options
        //localhost
        //manually entered address
        Column {
            anchors { bottom: parent.bottom; bottomMargin: 20 }
            spacing: 20
            width: 600 //allow plenty of room for the manually entered address
    
            //first row, localhost selection
            Rectangle {
                id: localHostOption
    
                height: 64; width:parent.width
                color: "transparent"
    
                Text{
                    id:localhostText
                    color: d.textColour
                    height:parent.height
                    verticalAlignment: Text.AlignVCenter
                    //: Button caption. Clicking it means the user is saying "make a network connection to the server that is running on the machine I am using".
                    text: qsTranslate("Startup", "Connect to local machine")
                    anchors.left: parent.left //put this on the left side
                    anchors.leftMargin: 5
                    font.pointSize: 14
                }
                Image{
                    id: iconLocal
                    anchors.right: parent.right //put this on the right side
                    source: "images/fake assets/arrow_right_green.png"
                    width: 64; height: 64
                    opacity: 0.7
                }
                MouseArea {
                    anchors.fill: parent
                    hoverEnabled: true
                    acceptedButtons: Qt.LeftButton
    
                    onClicked: {
                        connectionSelector.ipChosen("localhost", d.keyString);
                    }
                    onEntered: iconLocal.opacity = 1.0
                    onExited: iconLocal.opacity = 0.7
                }
            }
    
            //second row, manually-specified ip
            Rectangle {
                id: customIPOption
                property string ip: input.text
                visible: userAccessModel.isAuthenticated
                height:64; width: parent.width
                color: "transparent"
    
                Text{
                    id:addressLabel
                    height:parent.height
                    verticalAlignment: Text.AlignVCenter
                    anchors.left: parent.left
                    color: d.textColour
                    //: Button caption. Clicking it means the user is saying "make a network connection to a server running on another machine"
                    text: qsTranslate("Startup", "Connect to remote machine:")
                    font.pointSize: 14
                    anchors.leftMargin: 5
                }
                TextInput{
                    id: input
                    anchors.right: iconCustom.left
                    anchors.left: addressLabel.right
    
                    //couldn't get it to vertically align nicely.
                    //fixing the height achieves the same effect.
                    anchors.verticalCenter: addressLabel.verticalCenter
                    height: 23
    
                    color: d.textColour
                    font.pointSize: 14
                    font.italic: true
                    selectByMouse: true
    
                    //initially load the last-used-address
                    text: d.lastIpAddress
    
                    Keys.onPressed:{ //allow user to type ip and hit enter instead of clicking button
                        if( connectionSelector.opacity > 0.0 ){
                            if( event.key === Qt.Key_Return || event.key === Qt.Key_Enter ){
                                saveCustomIp(customIPOption.ip)
                                connectionSelector.ipChosen(customIPOption.ip, d.keyString)
                            }
                        }
                    }
                }
                Image{
                    id: iconCustom
                    anchors.right: parent.right
                    source: "images/fake assets/arrow_right_green.png"
                    width: 64; height: 64
                    opacity: 0.7
                    MouseArea {
                        anchors.fill: parent
                        hoverEnabled: true
                        acceptedButtons: Qt.LeftButton
                        onClicked: {
                            saveCustomIp(customIPOption.ip)
                            connectionSelector.ipChosen(customIPOption.ip, d.keyString)
                        }
                        onEntered: { iconCustom.opacity = 1.0; }
                        onExited: { iconCustom.opacity = 0.7; }
                    }
                }
            }
        }
    }
    

    As I say the onEntered and onExited work fine, just the clicked thats not working. I should stated:

    Qt Creator 4.2.1, Based on Qt 5.8.0 MSVC 2015, 32 bit


  • Moderators

    @SPlatten well, I can't see what could be the problem 🤔

    you can try removing the acceptedButtons property ( the default is already LeftButton) and try listening to onPressed: and onReleased, see if those come through



  • @J-Hilk , I just tried exactly that, commented out acceptButtons and added handlers for onPressed and onReleased, nothing, however the onEntered and onExited do still work.


  • Moderators

    @SPlatten mmmh,

    An idea could be, to move your localHostOption to it's own QML file, check that independently from your project and if that works as expected, import that one in your project


    Edit, if you're using QtCreator, simply right click in the Item, and select Refactoring -> Component in separate file.
    That will trigger a small wizard to help you in that process



  • @J-Hilk , I'm still quite new to QML, I've created a new QML file called localHostOption, how do I replace the Rectangle block in the ConnectionSelection.qml with the localHostOption from the file?

    I've imprted:

    import "../qml/localHostOption.qml" as localHostOption
    

    This file contains:

    import QtQuick 2.6
    import "Utils.js" as Utils
    
    Rectangle {
        id: localHostOption
    
        height: 64; width:parent.width
        color: "transparent"
    
        Text{
            id:localhostText
            color: d.textColour
            height:parent.height
            verticalAlignment: Text.AlignVCenter
            //: Button caption. Clicking it means the user is saying "make a network connection to the server that is running on the machine I am using".
            text: qsTranslate("Startup", "Connect to local machine")
            anchors.left: parent.left //put this on the left side
            anchors.leftMargin: 5
            font.pointSize: 14
        }
        Image{
            id: iconLocal
            anchors.right: parent.right //put this on the right side
            source: "images/fake assets/arrow_right_green.png"
            width: 64; height: 64
            opacity: 0.7
            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                acceptedButtons: Qt.LeftButton
                onClicked: {
                    connectionSelector.ipChosen("localhost", d.keyString);
                }
                onEntered: { iconLocal.opacity = 1.0; }
                onExited: { iconLocal.opacity = 0.7; }
            }
        }
    }
    

    Not sure how I then drop replace the existing block in the file with a reference to this?


  • Moderators

    @SPlatten
    your new qml file could look like this:

    import QtQuick 2.6
    
    Rectangle {
        id: localHostOption
    
        signal localHostChoosen()
        onLocalHostChoosen: console.log("local Host is choosen")
        property alias textColor: localhostText
    
        height: 64; width:parent.width
        color: "transparent"
    
        Text{
            id:localhostText
            height:parent.height
            verticalAlignment: Text.AlignVCenter
            //: Button caption. Clicking it means the user is saying "make a network connection to the server that is running on the machine I am using".
            text: qsTranslate("Startup", "Connect to local machine")
            anchors.left: parent.left //put this on the left side
            anchors.leftMargin: 5
            font.pointSize: 14
        }
        Image{
            id: iconLocal
            anchors.right: parent.right //put this on the right side
            source: "images/fake assets/arrow_right_green.png"
            width: 64; height: 64
            opacity: 0.7
        }
        MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            acceptedButtons: Qt.LeftButton
    
            onClicked: {
                localHostOption.localHostChoosen()
            }
            onEntered: iconLocal.opacity = 1.0
            onExited: iconLocal.opacity = 0.7
        }
    }
    


  • @J-Hilk , ok, so I created: LocalHostOption.qml

    import QtQuick 2.6
    import "Utils.js" as Utils
    
    Rectangle {
        id: localHostOption
        color: "transparent"
        height: 64
        width: parent.width
    
        Text{
            id:localhostText
            color: d.textColour
            height:parent.height
            verticalAlignment: Text.AlignVCenter
            //: Button caption. Clicking it means the user is saying "make a network connection to the server that is running on the machine I am using".
            text: qsTranslate("Startup", "Connect to local machine")
            anchors.left: parent.left //put this on the left side
            anchors.leftMargin: 5
            font.pointSize: 14
        }
        Image{
            id: iconLocal
            anchors.right: parent.right //put this on the right side
            source: "images/fake assets/arrow_right_green.png"
            width: 64
            height: 64
            opacity: 0.7
    
            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                acceptedButtons: Qt.LeftButton
                onClicked: {
                    connectionSelector.ipChosen("localhost", d.keyString);
                }
                onEntered: { iconLocal.opacity = 1.0; }
                onExited: { iconLocal.opacity = 0.7; }
            }
        }
    }
    

    And modified the original file, ConnectionSelector.qml:

    ////////////////////////////////////////////////////////////////////
    // ConnectionSelector.qml
    // Allows user to specify connecting to localhost or to a
    // manually entered ip address. This is not normally shown
    // as mostly the UI will be run using the auto-connect option
    // by specifying the IP at the command line.
    //
    // Note that unlike every other screen, this is more likely to
    // be mouse-driven than touch-driven.
    //
    import QtQuick 2.6
    import "Utils.js" as Utils
    
    Rectangle {
        id: connectionSelector
    
        //"private" variables
        QtObject {
            id:d
    /*        property string ipString: "" */
              property string keyString: ""
            property color textColour: "#ffffff"
            property string lastIpAddress: ""
        }
    
        Component.onCompleted: {
            initialiseIPandKey()
        }
    
        //loads previously-saved ip/key information from the database
        function initialiseIPandKey(){
            Utils.initialiseStorage("UI");
            var lastIpAddress = Utils.setting("lastIpAddress");
            var lastAccessKey = Utils.setting("lastAccessKey");
            if (lastIpAddress === undefined) {
                Utils.setSetting("lastIpAddress", "192.168.10.254");
            }
            if (lastAccessKey === undefined) {
                Utils.setSetting("lastAccessKey", "1.2.3.4");
            }
            lastIpAddress = Utils.setting("lastIpAddress");
            lastAccessKey = Utils.setting("lastAccessKey");
    
            d.lastIpAddress = lastIpAddress
            d.keyString = lastAccessKey
        }
    
        //save the ip for later so it's known when we reload
        function saveCustomIp(ip) {
            Utils.setSetting("lastIpAddress", ip)
        }
    
        //actually makes the connection happen by calling into the connection manager
        function ipChosen(ip, keyString) {
            connectionManagerModel.setConnectionAttributes(ip, keyString)
            connectionManagerModel.initialiseConnection()
        }
    
        //static background image
        Image {
            anchors.fill: parent
            id: backgroundImage
            source: "images/STARTUP_SHUTDOWN/startup_background.jpg"
        }
    
    
        //displays connection-state-appropriate text (see state machine for content)
        Text {
            id: licenceText
            anchors { top: parent.top; left: parent.left; leftMargin: 10; topMargin: 10 }
            font.pointSize: 10
            color:  userAccessModel.licenceExpired ? Utils.expiredLicenceColour() : Utils.splashScreenTextColor()
            text: (userAccessModel.isAuthenticated || userAccessModel.licenceExpired)
                    ? "Licenced to " +userAccessModel.authenticatedUser + ". Expires: " + userAccessModel.licenceExpiryDate
                    : "Not licenced for remote connections"
        }
    
        //two rows of connection options
        //localhost
        //manually entered address
        Column {
            anchors { bottom: parent.bottom; bottomMargin: 20 }
            spacing: 20
            width: 600 //allow plenty of room for the manually entered address
    
            //first row, localhost selection
            LocalHostOption {
                id: localHostOption
            }
    
            //second row, manually-specified ip
            Rectangle {
                id: customIPOption
                property string ip: input.text
                visible: userAccessModel.isAuthenticated
                height:64; width: parent.width
                color: "transparent"
    
                Text{
                    id:addressLabel
                    height:parent.height
                    verticalAlignment: Text.AlignVCenter
                    anchors.left: parent.left
                    color: d.textColour
                    //: Button caption. Clicking it means the user is saying "make a network connection to a server running on another machine"
                    text: qsTranslate("Startup", "Connect to remote machine:")
                    font.pointSize: 14
                    anchors.leftMargin: 5
                }
                TextInput{
                    id: input
                    anchors.right: iconCustom.left
                    anchors.left: addressLabel.right
    
                    //couldn't get it to vertically align nicely.
                    //fixing the height achieves the same effect.
                    anchors.verticalCenter: addressLabel.verticalCenter
                    height: 23
    
                    color: d.textColour
                    font.pointSize: 14
                    font.italic: true
                    selectByMouse: true
    
                    //initially load the last-used-address
                    text: d.lastIpAddress
    
                    Keys.onPressed:{ //allow user to type ip and hit enter instead of clicking button
                        if( connectionSelector.opacity > 0.0 ){
                            if( event.key === Qt.Key_Return || event.key === Qt.Key_Enter ){
                                saveCustomIp(customIPOption.ip)
                                connectionSelector.ipChosen(customIPOption.ip, d.keyString)
                            }
                        }
                    }
                }
                Image{
                    id: iconCustom
                    anchors.right: parent.right
                    source: "images/fake assets/arrow_right_green.png"
                    width: 64; height: 64
                    opacity: 0.7
                    MouseArea {
                        anchors.fill: parent
                        hoverEnabled: true
                        acceptedButtons: Qt.LeftButton
                        onClicked: {
                            saveCustomIp(customIPOption.ip)
                            connectionSelector.ipChosen(customIPOption.ip, d.keyString)
                        }
                        onEntered: { iconCustom.opacity = 1.0; }
                        onExited: { iconCustom.opacity = 0.7; }
                    }
                }
            }
        }
    }
    

    Recompiled and ran, everything looks the same and onClicked still doesn't work.


  • Moderators

    @SPlatten ok

    I have an idea!

    I think you have somewhere inside your draw hierarchy an other MouseArea, that lies "ontop" of your current component.

    That would explain, why hover is coming through, and click's don't.

    MouseAreas do not forward (automatically) the click/press/release events



  • @J-Hilk , I wish it was that straight forward, as far as I can see there is only one other QML document above this and it does not contain a MouseArea.


  • Moderators

    @SPlatten I'm sure it is :D

    Try it, load your LocalHostOption.qml directly no other component (you can use a new project)

    Window {
        id: window
    
        width: 120
        height: 60
    
        visible: true
    
        LocalHostOptions {
            anchors.fill: parent
        }
    }
    

Log in to reply