3
votes

I want to pass signal from one qml file to another qml file. So that when it gets the signal I can make another file visible Here is my main.qml

import QtQuick 1.1

Rectangle{
    id:main
    width:480
    height:272
    gradient: Gradient {
        GradientStop { position: 0.0; color: "light blue" }
        GradientStop { position: 1.0; color: "blue" }
    }
    Welcome{
        id:welcomePage
        width:parent.width
        height:parent.height
        visible:true
    }
    LoginPage{
        id:login
        width:parent.width
        height:parent.height
        visible:false
    }
    Connections{
        ignoreUnknownSignals: true
        onsigLogin:{welcomePage.visible=false
            login.visible=true
        }

    }

}

here goes my welcome.qml

import QtQuick 1.1

Rectangle{
    id:welcome
    width:480
    height:272
    signal sigLogin()

    gradient: Gradient {
        GradientStop { position: 0.0; color: "light blue" }
        GradientStop { position: 1.0; color: "blue" }
    }
    Text{
        text:"\n\t\tPRESS ENTER"
        font.bold:true
        font.pointSize: 17
    }
    Button {
        id: wel
        height:30;
        x:parent.width/2-30
        y:parent.height/2-30
        focus:true
        border.color:"black"
        opacity: activeFocus ? 1.0 : 0.5
        Text{
        text:"WELCOME"
            anchors.horizontalCenter:wel.horizontalCenter;
            anchors.verticalCenter:wel.verticalCenter;
        }
        Keys.onReturnPressed: {
            wel.focus=false
            welcome.sigLogin()
        }
    }
}

When I run this I get the following error

file:///home/sakshi/try1/main.qml:24:9: Cannot assign to non-existent property    "onsigLogin" 
         onsigLogin:{welcomePage.visible=false 
         ^ 

Can any one suggest me how to pass signal from one file and how to make changes when I get that signal?

3

3 Answers

3
votes

i got the answer for my question. i dont know whether it is proper but by doing this my code is working i just moved onsigLogin inside welcome block something like this

Welcome{id:welcomePage
    width:parent.width
    height:parent.height
    visible:true
    onSigLogin: {
        visible=false
        login.visible=true
    }
} 
2
votes

The simple answer is that you're using Connections wrong. From the documentation:

target : Object

This property holds the object that sends the signal.

If this property is not set, the target defaults to the parent of the Connection.

If set to null, no connection is made and any signal handlers are ignored until the target is not null.

So in your case, the target defaulted to main since it was the parent of the Connections object. Simply modifying your code like so:

Connections {
    target: welcomePage  // this is the critical part!
    ignoreUnknownSignals: true
    onSigLogin: {  // note capitalization of on*S*igLogin
        welcomePage.visible = false
        login.visible = true
    }
}

is sufficient to make it work as intended, because welcomePage is the one generating the signal.

1
votes

Don't call other objects, make signals or bind

Declarative languages, like QML are beautifully useful when you forget about imperative code. Use this pattern for whatever elements you need:

ElementOne{
    id: first
    width:parent.width
    height:parent.height
    visible: !second.loggedIn // <- Beautiful binding
}
ElementTwo{
    id: second
    width:parent.width
    height:parent.height
    property bool loggedIn: false // Internal to the ElementTwo.qml
    visible: true
}

Then your second element can just change it's own loggedIn property and Welcome can automatically react. This makes reusable components and avoids spagetti property assignment all over the place. QML is dangerously too easy.

There are other patterns you can use, like States, but mainly avoid imperative code in QML.