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

Interfacing qml and c++



  • Hello I am trying to change the property in qml file using some c++ code.
    But when i build it, it is giving following errors.

    The program has unexpectedly finished.
    "QQmlComponent:Component is not ready". Here is my code.

    void NTUserSettingsModel::installPulseWidthToFrequencyHandler()
    {
        NTUserSetting * pulseWidth = m_settingsMap.value(NTUserSetting::ID_PULSE_WIDTH);
        NTUserSetting * frequency  = m_settingsMap.value(NTUserSetting::ID_FREQUENCY);
    
        qCDebug(LC_NTUserSettingsModel())<< "pulseWidth is changed";
        QQmlEngine engine;
        QQmlComponent component(&engine, QUrl(QStringLiteral("Sources/QmlSources.qrc:/QML/Components/NTSpinBox.qml")));
        QObject *object = component.create();
        object->setProperty("color","white");
        delete object;
    
        if(pulseWidth && frequency)
        {
          connect(pulseWidth, &NTUserSetting::beforeValueChanged,   this,      &NTUserSettingsModel::adjustFrequencyForPulseWidth);
          connect(frequency,  &NTUserSetting::beforeValueChanged,   this,      &NTUserSettingsModel::adjustPulseWidthForFrequency);
        }
    }
    

    Is it correct way to give the path? How i have given inside my "QQmlComponent component". I think, it is not identifying the file in the path. How can i solve this issue? Thanks in advance.



  • @JennyAug13 said in Interfacing qml and c++:

    QQmlComponent component(&engine, QUrl(QStringLiteral("Sources/QmlSources.qrc:/QML/Components/NTSpinBox.qml")));

    try replacing this with

    QQmlComponent component(&engine, QUrl(QStringLiteral(":/QML/Components/NTSpinBox.qml")));


  • Moderators

    @JennyAug13 said in Interfacing qml and c++:
    Sources/QmlSources.qrc:/QML/Components/NTSpinBox.qml is not a valid url, thus the component never reaches the ready state.
    did you mean qrc:/QML/Components/NTSpinBox.qml instead?


  • Moderators

    I'm a bit confused here, does a QQmlEngine that is created as a local stack variable continue to exist after the end of the function scope?


  • Moderators

    @J.Hilk said in Interfacing qml and c++:

    I'm a bit confused here, does a QQmlEngine that is created as a local stack variable continue to exist after the end of the function scope?

    of course not. I haven't noticed this. :)
    The mentioned error message is not related to this, but this would definitively be the next issue.


  • Moderators

    @raven-worx
    alright. I thought maybe some magic happens somewhere ;-)

    this seems like a potential 3rd problem as well;
    Creating a coponent, setting a property and than deleting it in more or less the same step. The compiler may even skip
    the whole step during the optimization process.

    QObject *object = component.create();
        object->setProperty("color","white");
        delete object;
    


  • @raven-worx Yes it is ```
    QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/QML/Components/NTIntensityControl.qml")));


  • Moderators

    @JennyAug13
    anyway, like in your other post the biggest issue is:

    QObject *object = component.create();
    object->setProperty("color","white");
    delete object;
    


  • But the problem still exist, the problem is not with ```

    QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/QML/Components/NTIntensityControl.qml")));
    

    but donot know, how can i change property in my qml file using c++ code and here is my qml file for your reference.

    
    import QtQuick 2.3
    import QtQuick.Layouts 1.1
    
    import "../Theme"
    
    
    Item {
    
        id: ntSpinBox
    
        objectName: "ntSpinBox"
    
        ///////////////////////////////////////////////////////////////////////////
        // Properties
        ///////////////////////////////////////////////////////////////////////////
    
        /// the currently selected value
        property var    value:   undefined // using var for generic list value support
    
        /// the minimum value of the range
        property double minimumValue: 0.0
    
        /// the maximum value of the range
        property double maximumValue: 10.0
    
        /// the stepSize for incrementing / decrementing values
        property double stepSize:     1.0
    
        /// a list / array of values to select from
        property var    itemList:     undefined
    
        /// Color of the buttons
        property color  color:        Theme.palette.button
    
        // speed of continuous update (press and hold) in stepSizes / sec
        property int continuousSpeed: Theme.settings.spinBoxSpeed
    
        /// determine if the value can be decremented further
        readonly property bool canDec: (itemList === undefined) ?
                                           (value > minimumValue) :
                                           (selectedIndex > 0)
    
        /// determine if the value can be incremented further
        readonly property bool canInc: (itemList === undefined) ?
                                           (value < maximumValue) :
                                           (selectedIndex < (itemList.length-1))
    
        /// if an itemList is set, this property holds the index of the currently
        /// selected item
        readonly property int selectedIndex: d.listIndex
    
        /// size of a button, internally used only
        readonly property real buttonSize: Math.min(ntSpinBox.width / 2,
                                                    ntSpinBox.height)
    
        property bool greyout: false
    
        ///////////////////////////////////////////////////////////////////////////
        // Inherited Properties
        ///////////////////////////////////////////////////////////////////////////
    
        implicitWidth:  implicitHeight * 2 + Theme.diPaddingX
        implicitHeight: Theme.diControlHeight
    
        ///////////////////////////////////////////////////////////////////////////
        // Signals
        ///////////////////////////////////////////////////////////////////////////
    
        signal userSetVal();
        signal incBeyondMax(); ///< user tried to set a value > maximumValue
    
        ///////////////////////////////////////////////////////////////////////////
        // Slots
        ///////////////////////////////////////////////////////////////////////////
    
        Component.onCompleted: {
            d.updateListIndex();
        }
    
        onValueChanged: {
            d.updateListIndex();
        }
    
        ///////////////////////////////////////////////////////////////////////////
        // Private data
        ///////////////////////////////////////////////////////////////////////////
    
        QtObject
        {
            id: d
    
            property int  listIndex:    0
            property bool hasListItems: ntSpinBox.itemList !== undefined
            property real currentThreshold: ntSpinBox.maximumValue
    
            onListIndexChanged: {
                if (d.hasListItems) {
                    ntSpinBox.value = ntSpinBox.itemList[d.listIndex];
                }
            }
    
            function updateListIndex() {
                if (!d.hasListItems) {
                    return;
                }
                var newListIndex = itemList.indexOf(ntSpinBox.value);
                if (newListIndex !== d.listIndex && newListIndex !== -1) {
                    d.listIndex = newListIndex;
                }
            }
    
            /// set new value if it is in specified range
            function setValue(newVal) {
                if (newVal <= ntSpinBox.maximumValue && newVal >= ntSpinBox.minimumValue) {
                    ntSpinBox.value = newVal;
                    userSetVal();
                }
            }
    
            function setListIndex(newIdx) {
                if (newIdx >= 0 && newIdx < itemList.length) {
                    d.listIndex = newIdx;
                }
            }
    
            /// increment value by specified stepSize
            function inc() {
                var newVal = 0;
                if (d.hasListItems) {
                    newVal = d.listIndex+1;
                    setListIndex(newVal);
                }
                else {
                    newVal = ntSpinBox.value + ntSpinBox.stepSize;
                    setValue(newVal);
                }
                if(newVal > ntSpinBox.maximumValue) {
                    incBeyondMax();
                }
            }
    
            /// decrement value by specified stepSize
            function dec() {
                if (d.hasListItems) {
                    setListIndex(d.listIndex-1);
                }
                else {
                    setValue(ntSpinBox.value - ntSpinBox.stepSize);
                }
            }
        }
    
        ///////////////////////////////////////////////////////////////////////////
        // Child Components
        ///////////////////////////////////////////////////////////////////////////
    
        // Decrement Button
        NTActionButton {
    
            id: minusButton
    
            objectName: "minusButton"
    
            anchors.left: parent.left
    
            enabled: canDec
            greyout: ntSpinBox.greyout
    
            pressAndHoldEnable:   true
            pressAndHoldInterval: 1000 / continuousSpeed
    
            color:      ntSpinBox.color
            size:       ntSpinBox.buttonSize
            iconSource: itemList ? Theme.icons.back : Theme.icons.minus
            sound:      Theme.sounds.minusButtonSound
    
            onAction: {
                d.dec();
            }
        }
    
        // Increment Button
        NTActionButton {
    
            id: plusButton
    
            objectName: "plusButton"
    
            anchors.right: parent.right
    
            enabled: canInc
            greyout: ntSpinBox.greyout
    
            pressAndHoldEnable:   true
            pressAndHoldInterval: 1000 / continuousSpeed
    
            color:      ntSpinBox.color
            size:       ntSpinBox.buttonSize
            iconSource: itemList ? Theme.icons.next : Theme.icons.plus
            sound:      Theme.sounds.plusButtonSound
    
            onAction: {
                d.inc();
            }
        }
    }
    
    

Log in to reply