3

I have a C++ implemented Quick Item and it offeres multiple properties and Q_INVOKABLE methods with return values. Most of these methods depend on these properties.

Can I define a notify signal for methods? Or when binding to it, can I add additional dependencies so the method is evaluated again?

In this example I want all text items to be updated whenever theItem.something changes.

Screenshot of my example application

SimpleCppItem {
    id: theItem
    something: theSpinBox.value
}

RowLayout {
    SpinBox { id: theSpinBox; }

    Repeater {
        model: 10
        Text { text: theItem.computeWithSomething(index) }
    }
}

The implementation of the SimpleCppItem looks like this:

class SimpleCppItem : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(int something READ something WRITE setSomething NOTIFY somethingChanged)

public:
    explicit SimpleCppItem(QQuickItem *parent = Q_NULLPTR) :
        QQuickItem(parent),
        m_something(0)
    { }

    Q_INVOKABLE int computeWithSomething(int param)
    { return m_something + param; } //The result depends on something and param

    int something() const { return m_something; }
    void setSomething(int something)
    {
        if(m_something != something)
            Q_EMIT somethingChanged(m_something = something);
    }

Q_SIGNALS:
    void somethingChanged(int something);

private:
    int m_something;
};
feedc0de
  • 3,646
  • 8
  • 30
  • 55

1 Answers1

1

That is not possible with functions. But there are some workarouds:

"Small Hack" (You get warning M30: Warning, Do not use comma expressions Thanks to GrecKo, no warning anymore!

Repeater {
        model: 10
        Text {
            text: {theItem.something; return theItem.computeWithSomething(index);}
        }
    }

Or you connect every item in the repeater with the "somethingChanged" signal:

Repeater {
    model: 10
    Text {
        id: textBox
        text: theItem.computeWithSomething(index)
        Component.onCompleted: {
            theItem.somethingChanged.connect(updateText)
        }
        function updateText() {
            text = theItem.computeWithSomething(index)
        }
    }
}

===== ORIGNAL QUESTION =====

You can catch the signal in the QML file like this:

SimpleCppItem {
    id: theItem
    something: theSpinBox.value

    onSomethingChanged() {
       consoloe.log("Catched: ",something)
       //something ist the name of the parameter
    }
}
Hubi
  • 1,629
  • 15
  • 20
  • So I would need to update all text items that use the function? What if I dont know who uses it (because used in a seperate item file)? I would prefer defining that where the binding itself is defined. – feedc0de Jul 05 '17 at 09:17
  • After your changes: I dont think I can implement a seperate Q_PROPERTY for every combination of arguments to `computeWithSomething`. In my case the method is called from inside a Repeater that uses the index as argument. – feedc0de Jul 05 '17 at 09:33
  • 3
    You could avoid the warning by doing this instead : `{theItem.something; return theItem.computeWithSomething(index);}` – GrecKo Jul 05 '17 at 10:36
  • Is there a possibility that a future better optimized qml compiler removes the unused reference to the property from the binding? – feedc0de Jul 06 '17 at 07:37
  • I don't think so. The reference is btw. not completly unused, because qml registers a signal handler on the NOTIFY-signal of the theItem.something PROPERTY. It ends up in nearly the same code as in my second example. – Hubi Jul 06 '17 at 08:14