Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.5.1
-
Windows 10 22H2, MSVC 2019 x64
-
4fdaf22a5 (dev), 544f50597 (6.5), 585ad82fa (6.6), 3c0b8076e (dev), f7f9aa00a (6.5), 0be66b13b (6.6)
Description
Related to https://doc.qt.io/qt-6/qtqml-cppintegration-exposecppattributes.html#c-methods-and-the-this-object
Code
cppobj.h
class CppObj : public QObject { Q_OBJECT QML_ELEMENT public: CppObj(QObject* parent = nullptr) : QObject(parent) {} Q_INVOKABLE void sum(int a, int b) { qDebug().noquote() << this << QString("says %1 + %2 = %3").arg(a).arg(b).arg(a+b); } };
Main.qml
import QtQuick.Controls.Basic import InvokableProperty ApplicationWindow { width: 640 height: 480 visible: true property var qmlMethod: function(a, b) { console.log(`${this} says ${a} + ${b} = ${a+b}`) } property var cppMethod: objA.sum CppObj { id: objA; objectName: "objA" } CppObj { id: objB; objectName: "objB" } Button { text: "Calculate" onClicked: { qmlMethod(1, 2) qmlMethod.call(objB, 2, 1) objA.sum(3, 4) objA.sum.call(objB, 4, 3) cppMethod(5, 6) cppMethod.call(objB, 6, 5) } } }
Steps to reproduce
- Build and run the test code
- Click the button 3 times
Note: The enviroment variable QT_LOGGING_RULES="qt.qml.method.behavior=false;" is set to disable the note that is printed repeatedly in Qt 6.5:
Calling C++ methods with 'this' objects different from the one they were retrieved from is broken, due to historical reasons. The original object is used as 'this' object. You can allow the given 'this' object to be used by setting 'pragma NativeMethodBehavior: AcceptThisObject'
Qt 6.4.3 output, for every click (expected)
This shows the expected (but erroneous) historical C++ output. The QML output is correct.
qml: Main_QMLTYPE_3(0x2243e73ceb0) says 1 + 2 = 3 qml: CppObj(0x2243b840b40, "objB") says 2 + 1 = 3 CppObj(0x2243b840d60, name = objA) says 3 + 4 = 7 CppObj(0x2243b840d60, name = objA) says 4 + 3 = 7 CppObj(0x2243b840d60, name = objA) says 5 + 6 = 11 CppObj(0x2243b840d60, name = objA) says 6 + 5 = 11
Qt 6.5.1 output, for the 1st click (expected)
Without pragma NativeMethodBehavior: AcceptThisObject, the historical behaviour is preserved as expected.
qml: Main_QMLTYPE_3(0x1a177582a30) says 1 + 2 = 3 qml: CppObj(0x1a1745d30f0, "objB") says 2 + 1 = 3 CppObj(0x1a1745d2870, name = objA) says 3 + 4 = 7 CppObj(0x1a1745d2870, name = objA) says 4 + 3 = 7 CppObj(0x1a1745d2870, name = objA) says 5 + 6 = 11 CppObj(0x1a1745d2870, name = objA) says 6 + 5 = 11
Qt 6.5.1 output, for the 2nd and subsequent clicks (unexpected)
The outputs of the 1st click are not reproduced. Instead, we get "Too many arguments, ignoring 1" when invoking `cppMethod` (in contrast with `objA.sum.call(objB, 4, 3)` which produces the expected historical output)
qml: Main_QMLTYPE_3(0x1a177582a30) says 1 + 2 = 3 qml: CppObj(0x1a1745d30f0, "objB") says 2 + 1 = 3 CppObj(0x1a1745d2870, name = objA) says 3 + 4 = 7 CppObj(0x1a1745d2870, name = objA) says 4 + 3 = 7 expression for onClicked@qrc:/InvokableProperty/Main.qml:24 Too many arguments, ignoring 1 "Could not convert argument 0 at" "expression for onClicked@qrc:/InvokableProperty/Main.qml:24" Passing incomatible arguments to signals is not supported. expression for onClicked@qrc:/InvokableProperty/Main.qml:25 Too many arguments, ignoring 1 "Could not convert argument 0 at" "expression for onClicked@qrc:/InvokableProperty/Main.qml:25" Passing incomatible arguments to signals is not supported.
Use case
A customer has existing code where many Q_INVOKABLE methods are stored in properties and invoked directly, like 'cppMethod(5, 6)'
Other notes
- If using the test code from
QTBUG-114090instead of the one attached to this ticket, the 2nd click will crash at cppMethod.call(objB) on Qt 6.5.1 - There is a typo in the warnings above: "incomatible"
Attachments
Issue Links
- relates to
-
QTBUG-114090 Need "NativeMethodBehavior: AcceptThisObject" (or a separate pragma) to apply to JS functions
- Closed