Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
5.5.1
Description
It is not possible to access idx.row if idx is a QVariant containing a QModelIndex.
There does not appear to be an alternative way to make the index known to the javascript engine for a function call, except by using QJSEngine::toScriptValue which wraps in that way.
#include <QGuiApplication> #include <QQuickView> #include <QQmlEngine> #include <QQmlContext> #include <QStandardItemModel> #include <QDebug> class Something : public QObject { Q_OBJECT Q_PROPERTY(QJSValue theFunction READ function WRITE setFunction NOTIFY functionChanged) Q_PROPERTY(QJSValue theRectFunction READ rectFunction WRITE setRectFunction NOTIFY rectFunctionChanged) public: Something(QObject* = 0) { } void setFunction(const QJSValue& function) { if (!mFunction.equals(function)) { mFunction = function; Q_ASSERT(mFunction.isCallable()); Q_EMIT functionChanged(); } } QJSValue function() const { return mFunction; } void setRectFunction(const QJSValue& function) { if (!mRectFunction.equals(function)) { mRectFunction = function; Q_ASSERT(mRectFunction.isCallable()); Q_EMIT rectFunctionChanged(); } } QJSValue rectFunction() const { return mRectFunction; } Q_INVOKABLE void callFunction(const QModelIndex& idx) { qDebug() << "Something::callFunction" << idx; QJSValueList args = QJSValueList() << qjsEngine(this)->toScriptValue(idx); mFunction.call(args).toVariant(); } Q_INVOKABLE void callRectFunction(const QRect& rect) { qDebug() << "Something::callRectFunction" << rect; QJSValueList args = QJSValueList() << qjsEngine(this)->toScriptValue(rect); mRectFunction.call(args).toVariant(); } Q_SIGNALS: void functionChanged(); void rectFunctionChanged(); private: mutable QJSValue mFunction; mutable QJSValue mRectFunction; }; int main(int argc, char** argv) { QGuiApplication app(argc, argv); QStandardItemModel model; model.appendRow(new QStandardItem("First")); model.appendRow(new QStandardItem("Second")); qmlRegisterType<Something>("Things", 1, 0, "Something"); QQuickView view; view.engine()->rootContext()->setContextProperty("_model", &model); view.setSource(QUrl("main.qml")); view.show(); return app.exec(); } #include "main.moc"
import QtQuick 2.3 import Things 1.0 Rectangle { id: root width: 560 height: 360 Something { id: st theFunction: function(idx) { console.log("theFunction idx", idx); console.log("theFunction row", idx.row); return 42; } theRectFunction: function(rect) { console.log("theFunction rect", rect); console.log("theFunction rectWidth", rect.width); } } Text { id: textElement text: "Click" width: 200 height: 30 MouseArea { anchors.fill: parent onClicked: { var idx = _model.index(0, 0); console.log("onClicked: idx", idx); console.log("onClicked: row", idx.row); st.callFunction(idx); var rect = Qt.rect(50, 50, 100, 100); console.log("onClicked: rect", rect) console.log("onClicked: rectWidth", rect.width) st.callRectFunction(rect) } } } }
Output after clicking:
$ ./QTBUG-48073.app/Contents/MacOS/QTBUG-48073 qml: onClicked: idx QModelIndex(0,0,0x7ff18a5733e0,QStandardItemModel(0x7fff5aed4880)) qml: onClicked: row 0 Something::callFunction QModelIndex(0,0,0x7ff18a5733e0,QStandardItemModel(0x7fff5aed4880)) qml: theFunction idx QVariant(QModelIndex) qml: theFunction row undefined qml: onClicked: rect QRectF(50, 50, 100, 100) qml: onClicked: rectWidth 100 Something::callRectFunction QRect(50,50 100x100) qml: theFunction rect QVariant(QRect) qml: theFunction rectWidth undefined