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

Property change signal handler sometimes not working with Qt 5.12.



  • Hi. Have a fairly large application that uses Loader to show various screens in an ApplicationWindow. A lot of these screens use a onVisibleChanged handler. Recently upgraded from Qt 5.9.4 to 5.12.7 and found that the onVisibleChanged handlers stopped working after the upgrade. Some screens are okay, but most are not. Anyone else had this problem or have an idea as to the cause?

    It appears to be more than just onVisibleChanged not working. I ran tests with onFocusChanged and it does not work either on the screens where onVisibleChanged isn't working.

    It is very weird that the property changed signal handler works on some screens and not on others. I thought maybe this might be a bug in 5.12.7, but testing with 5.12.6 had the same result. 5.12 is very mature and my searching on the forum or google didn't find others with this problem - so it is likely that there is a problem in the code that 5.9.4 tolerates, but 5.12 does not. Any ideas?

    It appears that the visibleChanged signal is being sent because I can connect it to a function and this seems to work every time. See examples below:

    Here's what does NOT work on some screens:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import "qrc:/controls"
    Item {
        id: screen1
        property int index: 0
        signal pageLoadRequest(string name, int index)
        ColumnLayout {	
        //....
        }
        Component.onCompleted: {
            console.log("screen1 Component.onCompleted");
        }
    	
    	// This onVisibleChanged hander never runs on SOME screens when build with Qt 5.12.6 or 5.12.7!
        onVisibleChanged: {
            console.log("screen1 onVisibleChanged -- visible:", visible);
        }
    }
    

    If I connect visibleChanged to my own java script function, then this always seems to work with 5.12

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import "qrc:/controls"
    Item {
        id: screen1
        property int index: 0
        signal pageLoadRequest(string name, int index)
        ColumnLayout {	
        //....
        }
        Component.onCompleted: {
            console.log("screen1 Component.onCompleted");
    	
            // Connecting visibleChanged signal to our own handler seems to work around
            // the problem - although this makes no sense!
            visibleChanged.connect(handleVisibleChanged);
        }
    
        // This onVisibleChanged handler never runs for some reason...
        onVisibleChanged: {
            console.log("screen1 onVisibleChanged -- visible:", visible);
        }
    
        // But connecting visibleChanged to this function does work. 
        function handleVisibleChanged() {
            console.log("screen1 handleVisibleChanged()", visible);
            if (visible === false) {
                console.log("screen1 handleVisibleChanged()...found visible to be false.");
    			// Do stuff here.
            }
        }
    }
    

    Thank you for taking time to read this post. Please let me know if you have any ideas on what the problem might be.



  • @MRD7 hi, can you test with Qt5.13 or 14 ?


  • Qt Champions 2017

    visibleChanged() signal will come only if the visible is really changed. It can't happen that signal is not sent. Most probably it is issue that signal itself is not emitted. This can happen because visibility is not really changed at all. It may be already visible=true & again setting to true or visible=false & again trying to set the same to false.

    I request you to check the what is the value of visibility flag every time. This should help you.



  • @LeLev

    I tested with qt 5.14.1 and got the same result as with 5.12.6&7...the onVisibleChanged handler doesn't run for some reason.



  • @dheerendra

    The visibleChanged() signal is being emitted. As my original post and code excerpt tried to explain, I can connect the visibleChanged signal to my own handler and it will get invoked when leave the screen. It is just that the onVisibleChanged handler won't work for some reason.

    The link https://doc.qt.io/qt-5/qml-qtqml-connections.html#details explains that there are 3 conditions where an an "on<Signal>" handler won't work:
    1. Multiple connections to the same signal are required
    2. Creating connections outside the scope of the signal sender
    3. Connecting to targets not defined in QML.

    I think the 2nd in the list may be the only one that might apply since we use loader. Could this be the case? If so, I don't understand why it works fine (reliably) with qt 5.9.4. I haven't taken time to bisect between 5.9.4 and 5.12.6 to see where it stopped working. I will probably do that later. These versions are all so mature though and I don't find any bug reports - so it seems like it must be a problem on our end. We can add connections between the visibleChanged signal and our own Java script function if it is a case where 5.9.4 tolerated our usage, but later versions do not. I'm just trying to understand the problem before making changes.


  • Qt Champions 2018

    @MRD7 said in Property change signal handler sometimes not working with Qt 5.12.:

    The link https://doc.qt.io/qt-5/qml-qtqml-connections.html#details explains that there are 3 conditions where an an "on<Signal>" handler won't work:
    1. Multiple connections to the same signal are required
    2. Creating connections outside the scope of the signal sender
    3. Connecting to targets not defined in QML.

    Those conditions don't apply to you. Those are to explain when you can't actually write on<Signal> because there is no place to.

    #1 is :

    onSignal: foo()
    onSignal: bar() // this will error out because there is already one similar signal handler
    

    #2 and #3 are :
    If you have an object declared outside your scope, you can't do onSignal: baz() because its scope is external.

    example :

    ApplicationWindow {
        // how do connect to a signal declared in a singleton or a context property ?
        // we can't because onSignal: ... is a signal handler for a signal of the current scope, ApplicationWindow here
    }
    

    Do you mind posting a minimal reproducible example of your problem so we can test ouselves?


Log in to reply