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

Sending a signal from parent qml to page in stack



  • I have a main qml file with a C++ backend which reads some data and provides it to qml to update displays.

    main.qml

    ApplicationWindow {
        id: root
        visible: true
        width: 800
        height: 400
        title: qsTr("Stack")
    
    property real value: 0
    
        Backend {
            id: typeFromCplusplus
    
            onValueChanged: value = value
    
            onFunctionComplete: {
                 value = 0
            }
        }
    
    
    Rest of code for stack including page 1....
    

    Then on page 1 I have some bindings which update the ValueLCD text as new data comes in and even a signal to update again after some maths. This all works perfectly. In fact in the actual application it works across four pages.

    Page {
        width: root.width
        height: root.height
        id: tableSawPage
    
        title: qsTr("page1")
    
        Binding {
            target: valueLCD
            property: 'text'
            value: (root.value).toFixed(1)
        }
    
       signal buttonPushedonThisPage
        onButtonPushedonThisPage: valueLCD.text = (root.value - 1).toFixed(1)
    
    

    What I can't get to happen is to update the display when the C++ function on the main page is completed. I have tried sending signals, making connections and bindings; but I can't seem to get anything to work when it is going "down the hierarchy"?



  • @Dave_022 said in Sending a signal from parent qml to page in stack:

    What I can't get to happen is to update the display when the C++ function on the main page is completed

    What probably happens is that your pages are completed after your C++ backend object completes and issues the functionComplete() signal.

    When it comes to controlling object creation order, QML is really horrible and I still have not figured out a 100% fool-proof method for it myself when dealing with dynamically created objects and dynamically populated layouts with model-based views etc. I found the Component.onCompleted handler for model-based view objects to be completely unreliable because it happens to be sometimes triggered before all the delegates have been created?

    In my current app, I tried to replace a QML type with a functionally equivalent custom type in C++ (an XmlListModel to be more precise) which populates the model faster than the standard QML type, but this breaks my app because of object creation order issues: apparently, it populates so much faster that some other UI elements (among which a ListView with GridView delegates) that are modified based on the data in the XML data view are not yet created. For the moment, I have abandoned the usage of this faster C++ model type because I couldn't solve this issue.

    Is it possible in your case to defer the creation of your Backend to until after all your QML visual items (I guess here page1) are completed, e.g. by using the Component.onCompleted slot of page1 (hoping all child elements of page1 especially valueLCD are indeed available at that time), and then create your Backend dynamically?

    ApplicationWindow {
        id: root
        ...
       property real value: 0
       property Backend backend
    
       Component {
              id: backendComponent
              Backend {
                     onFunctionComplete: {
                            value = 0
                   }
              }
    }
    
    Page  {
          id: page1
          ...
         Component.onCompleted: {
               root.backend = backendComponent.createObject(root)
         }
    }
    

    Or something like that ?

    P.S. what's onValueChanged: value = value for in your Backend snipped above?
    P.S.2: Anyone who can explain me how you can 100% control object creation order (of fully completed objects, that is, with all their children - which may in turn be complex views) in QML, please teach me!



  • onValueChanged: value = value
    

    Is actually serial data from an Arduino. the actual function then divides the number by 10 and rounds it.

    When this happens this does cause and update; in fact it does it on 4 seperate pages textfields.

    In reality the qml sends a distance to a serial write function which then directs the Arduino to use accelStepper to move steppers which then returns position back through the serial port to update a "DRO" style textfield. There are some flaws in the way it works....

    1. The positions returned are a bit false as it is not a closed loop system so only actually reads what the stepper has sent out.

    2. Also the qml sending signal also sets the textfield to update the data returned can only read one stepper at a time. Therefore if you set a distance to one motor and then send another distance before the data read has finished then the updates will be wrong.

    I guess I would have to make the Arduino return which stepper the 'DRO value' was form i.e. x10, x11 etc that way it could return data from multiple steppers at once and then be parsed out.... However this would take a complete rewrite, and I have struggled enough to get this far....


Log in to reply