diff options
19 files changed, 294 insertions, 12 deletions
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt index 5781b03573..686c9dfb24 100644 --- a/src/qml/CMakeLists.txt +++ b/src/qml/CMakeLists.txt @@ -359,6 +359,7 @@ qt_internal_add_qml_module(Qml qmltc/supportlibrary/qqmlcppbinding.cpp qmltc/supportlibrary/qqmlcpponassignment_p.h qmltc/supportlibrary/qqmlcpponassignment.cpp + qmltc/supportlibrary/qqmlcpptypehelpers_p.h DEFINES BUILDING_QT__ ENABLE_ASSEMBLER_WX_EXCLUSIVE=1 diff --git a/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp b/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp index 732d915b99..eda9009bb7 100644 --- a/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp +++ b/src/qml/doc/snippets/qmltc/special/HelloWorld.qml.cpp @@ -31,7 +31,7 @@ public: void setHello(const QString& hello_); QString hello(); QBindable<QString> bindableHello(); - Q_INVOKABLE void printHello(QString prefix, QString suffix); + Q_INVOKABLE void printHello(passByConstRefOrValue<QString> prefix, passByConstRefOrValue<QString> suffix); // ... }; diff --git a/src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h b/src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h new file mode 100644 index 0000000000..2470d87efe --- /dev/null +++ b/src/qml/qmltc/supportlibrary/qqmlcpptypehelpers_p.h @@ -0,0 +1,28 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQMLCPPTYPEHELPERS_H +#define QQMLCPPTYPEHELPERS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <type_traits> + +/*! \internal + Used by Qmltc to decide when value types should be passed by value or reference. + */ +template<typename T> +using passByConstRefOrValue = + std::conditional_t<((sizeof(T) > 3 * sizeof(void *)) || !std::is_trivial_v<T>), const T &, + T>; + +#endif // QQMLCPPTYPEHELPERS_H diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 8ce58cdcca..b44550cade 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -986,8 +986,69 @@ void QQmlJSImportVisitor::checkSignals() const auto signalParameters = signalMethod->parameters(); QHash<QString, qsizetype> parameterNameIndexes; - for (int i = 0; i < signalParameters.size(); i++) - parameterNameIndexes[signalParameters[i].name()] = i; + // check parameter positions and also if signal is suitable for onSignal handler + for (int i = 0, end = signalParameters.size(); i < end; ++i) { + auto &p = signalParameters[i]; + parameterNameIndexes[p.name()] = i; + + auto signalName = [&]() { + if (signal) + return u" called %1"_s.arg(*signal); + return QString(); + }; + auto type = p.type(); + if (!type) { + m_logger->log( + QStringLiteral( + "Type %1 of parameter %2 in signal%3 was not found, but is " + "required to compile %4. Did you add all import paths?") + .arg(p.typeName(), p.name(), signalName(), pair.first), + qmlSignalParameters, location); + continue; + } + + if (type->isComposite()) + continue; + + // only accept following parameters for non-composite types: + // * QObjects by pointer (nonconst*, const*, const*const,*const) + // * Value types by value (QFont, int) + // * Value types by const ref (const QFont&, const int&) + + auto parameterName = [&]() { + if (p.name().isEmpty()) + return QString(); + return u" called %1"_s.arg(p.name()); + }; + switch (type->accessSemantics()) { + case QQmlJSScope::AccessSemantics::Reference: + if (!p.isPointer()) + m_logger->log(QStringLiteral("Type %1 of parameter%2 in signal%3 should be " + "passed by pointer to be able to compile %4. ") + .arg(p.typeName(), parameterName(), signalName(), + pair.first), + qmlSignalParameters, location); + break; + case QQmlJSScope::AccessSemantics::Value: + case QQmlJSScope::AccessSemantics::Sequence: + if (p.isPointer()) + m_logger->log( + QStringLiteral( + "Type %1 of parameter%2 in signal%3 should be passed by " + "value or const reference to be able to compile %4. ") + .arg(p.typeName(), parameterName(), signalName(), + pair.first), + qmlSignalParameters, location); + break; + case QQmlJSScope::AccessSemantics::None: + m_logger->log( + QStringLiteral("Type %1 of parameter%2 in signal%3 required by the " + "compilation of %4 cannot be used. ") + .arg(p.typeName(), parameterName(), signalName(), pair.first), + qmlSignalParameters, location); + break; + } + } if (pair.second.size() > signalParameters.size()) { m_logger->log(QStringLiteral("Signal handler for \"%2\" has more formal" diff --git a/src/qmlcompiler/qqmljsmetatypes_p.h b/src/qmlcompiler/qqmljsmetatypes_p.h index 593a16b0c4..823a1849e5 100644 --- a/src/qmlcompiler/qqmljsmetatypes_p.h +++ b/src/qmlcompiler/qqmljsmetatypes_p.h @@ -135,6 +135,8 @@ public: void setType(QWeakPointer<const QQmlJSScope> type) { m_type = type; } Constness typeQualifier() const { return m_typeQualifier; } void setTypeQualifier(Constness typeQualifier) { m_typeQualifier = typeQualifier; } + bool isPointer() const { return m_isPointer; } + void setIsPointer(bool isPointer) { m_isPointer = isPointer; } friend bool operator==(const QQmlJSMetaParameter &a, const QQmlJSMetaParameter &b) { @@ -159,6 +161,7 @@ private: QString m_typeName; QWeakPointer<const QQmlJSScope> m_type; Constness m_typeQualifier = NonConst; + bool m_isPointer = false; }; class QQmlJSMetaMethod diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index ec0a90643d..e3d8bafeb3 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -508,6 +508,8 @@ QTypeRevision QQmlJSScope::resolveType( if (const QString typeName = parameter.typeName(); !parameter.type() && !typeName.isEmpty()) { const auto type = findType(typeName, context, usedTypes); + if (type.scope && type.scope->isReferenceType()) + parameter.setIsPointer(true); parameter.setType({ type.scope }); } } diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h index 9586d1c333..127d58abcc 100644 --- a/src/qmlcompiler/qqmljsscope_p.h +++ b/src/qmlcompiler/qqmljsscope_p.h @@ -561,6 +561,7 @@ public: void setAccessSemantics(AccessSemantics semantics) { m_semantics = semantics; } AccessSemantics accessSemantics() const { return m_semantics; } bool isReferenceType() const { return m_semantics == QQmlJSScope::AccessSemantics::Reference; } + bool isValueType() const { return m_semantics == QQmlJSScope::AccessSemantics::Value; } bool isIdInCurrentQmlScopes(const QString &id) const; bool isIdInCurrentJSScopes(const QString &id) const; diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 6f40b1d42f..8528d39f0f 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -428,6 +428,7 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM QString name; QString type; bool isConstant = false; + bool isPointer = false; for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) { UiObjectMember *member = it->member; @@ -443,9 +444,9 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM } else if (id == QLatin1String("type")) { type = readStringBinding(script); } else if (id == QLatin1String("isPointer")) { - // ### unhandled + isPointer = readBoolBinding(script); } else if (id == QLatin1String("isConstant")) { - isConstant = true; + isConstant = readBoolBinding(script); } else if (id == QLatin1String("isReadonly")) { // ### unhandled } else if (id == QLatin1String("isList")) { @@ -458,6 +459,7 @@ void QQmlJSTypeDescriptionReader::readParameter(UiObjectDefinition *ast, QQmlJSM QQmlJSMetaParameter p(name, type); p.setTypeQualifier(isConstant ? QQmlJSMetaParameter::Const : QQmlJSMetaParameter::NonConst); + p.setIsPointer(isPointer); metaMethod->addParameter(std::move(p)); } diff --git a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt index e81364d3e5..dc9a25a33a 100644 --- a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt +++ b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt @@ -20,6 +20,7 @@ set(cpp_sources cpptypes/typewithmanyproperties.h cpptypes/singletontype.h cpptypes/singletontype.cpp + cpptypes/typewithsignal.h ) set(qml_sources @@ -105,6 +106,7 @@ set(qml_sources aliases.qml inlineComponentsFromDifferentFiles.qml singletons.qml + mySignals.qml # support types: DefaultPropertySingleChild.qml diff --git a/tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h b/tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h new file mode 100644 index 0000000000..139b431a40 --- /dev/null +++ b/tests/auto/qml/qmltc/QmltcTests/cpptypes/typewithsignal.h @@ -0,0 +1,34 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef TYPEWITHSIGNAL_H +#define TYPEWITHSIGNAL_H + +#include <QtCore/qobject.h> +#include <QtQml/qqmlregistration.h> +#include <QtGui/qfont.h> + +class TypeWithSignal : public QObject +{ + Q_OBJECT + QML_ELEMENT + +Q_SIGNALS: + // value types by value + void signalWithPrimitive(int); + void signalWithGadget(QFont); + + // value types by const reference + void signalWithConstReferenceToGadget(const QFont &); + void signalWithConstReferenceToPrimitive(const int &); + + // object by pointers + void signalWithPointer(QObject *); + void signalWithPointerToConst(const QObject *); + void signalWithPointerToConst2(QObject const *); + void signalWithConstPointer(QObject *const); + void signalWithConstPointerToConst(const QObject *const); + void signalWithConstPointerToConst2(QObject const *const); +}; + +#endif // TYPEWITHSIGNAL_H diff --git a/tests/auto/qml/qmltc/QmltcTests/mySignals.qml b/tests/auto/qml/qmltc/QmltcTests/mySignals.qml new file mode 100644 index 0000000000..c79a0518c2 --- /dev/null +++ b/tests/auto/qml/qmltc/QmltcTests/mySignals.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QmltcTests +import QtQuick + + +TypeWithSignal { + property int primitive + property font gadget + property QtObject object + + // value types by value + onSignalWithPrimitive: (x) => { primitive = x; } + onSignalWithGadget: (x) => { gadget = x; } + + // value types by const reference + onSignalWithConstReferenceToGadget: (x) => { gadget = x; } + + // object by pointers + onSignalWithPointer: (x) => { object = x; } + onSignalWithPointerToConst: (x) => { object = x; } + onSignalWithPointerToConst2: (x) => { object = x; } + onSignalWithConstPointer: (x) => { object = x; } + onSignalWithConstPointerToConst: (x) => { object = x; } + onSignalWithConstPointerToConst2: (x) => { object = x; } +} diff --git a/tests/auto/qml/qmltc/tst_qmltc.cpp b/tests/auto/qml/qmltc/tst_qmltc.cpp index af03af264c..06d63333fc 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.cpp +++ b/tests/auto/qml/qmltc/tst_qmltc.cpp @@ -80,6 +80,7 @@ #include "testprivateproperty.h" #include "singletons.h" +#include "mysignals.h" // Qt: #include <QtCore/qstring.h> @@ -3124,4 +3125,61 @@ void tst_qmltc::singletons() QCOMPARE(createdByComponent->property("qmlSingleton2"), 100); } } + +void tst_qmltc::constSignalParameters() +{ + QQmlEngine e; + PREPEND_NAMESPACE(mySignals) fromQmltc(&e); + + int primitive = 123; + QFont defaultGadget; + QFont gadget; + gadget.setBold(true); + QQuickItem myItem; + myItem.setObjectName("New Name"); + + // by value + fromQmltc.setPrimitive(123); + emit fromQmltc.signalWithPrimitive(primitive); + QCOMPARE(fromQmltc.primitive(), primitive); + + fromQmltc.setGadget(defaultGadget); + emit fromQmltc.signalWithGadget(gadget); + QCOMPARE(fromQmltc.gadget(), gadget); + + // by const ref + fromQmltc.setPrimitive(123); + emit fromQmltc.signalWithConstReferenceToPrimitive(primitive); + QCOMPARE(fromQmltc.primitive(), primitive); + + fromQmltc.setGadget(defaultGadget); + emit fromQmltc.signalWithConstReferenceToGadget(gadget); + QCOMPARE(fromQmltc.gadget(), gadget); + + // by pointer + fromQmltc.setObject(nullptr); + emit fromQmltc.signalWithPointer(&myItem); + QCOMPARE(fromQmltc.object(), &myItem); + + fromQmltc.setObject(nullptr); + emit fromQmltc.signalWithPointerToConst(&myItem); + QCOMPARE(fromQmltc.object(), &myItem); + + fromQmltc.setObject(nullptr); + emit fromQmltc.signalWithPointerToConst2(&myItem); + QCOMPARE(fromQmltc.object(), &myItem); + + fromQmltc.setObject(nullptr); + emit fromQmltc.signalWithConstPointer(&myItem); + QCOMPARE(fromQmltc.object(), &myItem); + + fromQmltc.setObject(nullptr); + emit fromQmltc.signalWithConstPointerToConst(&myItem); + QCOMPARE(fromQmltc.object(), &myItem); + + fromQmltc.setObject(nullptr); + emit fromQmltc.signalWithConstPointerToConst2(&myItem); + QCOMPARE(fromQmltc.object(), &myItem); +} + QTEST_MAIN(tst_qmltc) diff --git a/tests/auto/qml/qmltc/tst_qmltc.h b/tests/auto/qml/qmltc/tst_qmltc.h index ff55401c14..05a05bf9b6 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.h +++ b/tests/auto/qml/qmltc/tst_qmltc.h @@ -90,4 +90,5 @@ private slots: void aliases(); void inlineComponentsFromDifferentFiles(); void singletons(); + void constSignalParameters(); }; diff --git a/tests/auto/qml/qmltc_qprocess/CMakeLists.txt b/tests/auto/qml/qmltc_qprocess/CMakeLists.txt index 04d2084d4f..d936e2c757 100644 --- a/tests/auto/qml/qmltc_qprocess/CMakeLists.txt +++ b/tests/auto/qml/qmltc_qprocess/CMakeLists.txt @@ -20,6 +20,8 @@ qt6_add_qml_module(tst_qmltc_qprocess AUTO_RESOURCE_PREFIX SOURCES cpptypes/testtype.h + DEPENDENCIES + QtQuick/auto QML_FILES data/dummy.qml data/inlineComponentInvalidAlias.qml @@ -30,6 +32,7 @@ qt6_add_qml_module(tst_qmltc_qprocess data/inlineComponentWithEnum.qml data/singletonUncreatable.qml data/uncreatable.qml + data/invalidSignalHandlers.qml ) set(common_libraries diff --git a/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h b/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h index 6082870c76..2130004def 100644 --- a/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h +++ b/tests/auto/qml/qmltc_qprocess/cpptypes/testtype.h @@ -7,6 +7,7 @@ #include <QtQmlIntegration/qqmlintegration.h> #include <QtCore/qobject.h> #include <QtQml/qqmlregistration.h> +#include <QtGui/qfont.h> class TypeWithVersionedAlias : public QObject { @@ -67,6 +68,19 @@ class NormalType : public QObject } }; +class TypeWithSignals : public QObject +{ + Q_OBJECT + QML_ELEMENT +public: +Q_SIGNALS: + void signalWithConstPointerToGadget(const QFont *); // not allowed + void signalWithConstPointerToGadgetConst(const QFont *const); // not allowed + void signalWithPointerToGadgetConst(QFont *const); // not allowed + void signalWithPointerToGadget(QFont *); // not allowed + void signalWithPrimitivePointer(int *); + void signalWithConstPrimitivePointer(const int *); +}; #endif // TESTTYPE_H diff --git a/tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml b/tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml new file mode 100644 index 0000000000..a2a100ab3b --- /dev/null +++ b/tests/auto/qml/qmltc_qprocess/data/invalidSignalHandlers.qml @@ -0,0 +1,10 @@ + +TypeWithSignals +{ + onSignalWithConstPointerToGadget: (x) => { console.log(x); } + onSignalWithConstPointerToGadgetConst: (x) => { console.log(x); } + onSignalWithPointerToGadgetConst: (x) => { console.log(x); } + onSignalWithPointerToGadget: (x) => { console.log(x); } + onSignalWithPrimitivePointer: (x) => { console.log(x); } + onSignalWithConstPrimitivePointer: (x) => { console.log(x); } +} diff --git a/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp b/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp index 04b3426298..1cea44206f 100644 --- a/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp +++ b/tests/auto/qml/qmltc_qprocess/tst_qmltc_qprocess.cpp @@ -50,6 +50,7 @@ private slots: void invalidAliasRevision(); void topLevelComponent(); void dashesInFilename(); + void invalidSignalHandlers(); }; #ifndef TST_QMLTC_QPROCESS_RESOURCES @@ -241,5 +242,24 @@ void tst_qmltc_qprocess::dashesInFilename() } } +void tst_qmltc_qprocess::invalidSignalHandlers() +{ + { + const auto errors = runQmltc(u"invalidSignalHandlers.qml"_s, false); + QVERIFY(errors.contains( + u"invalidSignalHandlers.qml:4:5: Type QFont of parameter in signal called signalWithConstPointerToGadget should be passed by value or const reference to be able to compile onSignalWithConstPointerToGadget. [signal-handler-parameters]"_s)); + QVERIFY(errors.contains( + u"invalidSignalHandlers.qml:5:5: Type QFont of parameter in signal called signalWithConstPointerToGadgetConst should be passed by value or const reference to be able to compile onSignalWithConstPointerToGadgetConst. [signal-handler-parameters]"_s)); + QVERIFY(errors.contains( + u"invalidSignalHandlers.qml:6:5: Type QFont of parameter in signal called signalWithPointerToGadgetConst should be passed by value or const reference to be able to compile onSignalWithPointerToGadgetConst. [signal-handler-parameters]"_s)); + QVERIFY(errors.contains( + u"invalidSignalHandlers.qml:7:5: Type QFont of parameter in signal called signalWithPointerToGadget should be passed by value or const reference to be able to compile onSignalWithPointerToGadget. [signal-handler-parameters]"_s)); + QVERIFY(errors.contains( + u"invalidSignalHandlers.qml:8:5: Type int of parameter in signal called signalWithPrimitivePointer should be passed by value or const reference to be able to compile onSignalWithPrimitivePointer. [signal-handler-parameters]"_s)); + QVERIFY(errors.contains( + u"invalidSignalHandlers.qml:9:5: Type int of parameter in signal called signalWithConstPrimitivePointer should be passed by value or const reference to be able to compile onSignalWithConstPrimitivePointer. [signal-handler-parameters]"_s)); + } +} + QTEST_MAIN(tst_qmltc_qprocess) #include "tst_qmltc_qprocess.moc" diff --git a/tools/qmltc/qmltccodewriter.cpp b/tools/qmltc/qmltccodewriter.cpp index 68bd803b15..c4c5c30f83 100644 --- a/tools/qmltc/qmltccodewriter.cpp +++ b/tools/qmltc/qmltccodewriter.cpp @@ -137,6 +137,7 @@ void QmltcCodeWriter::writeGlobalHeader(QmltcOutputWrapper &code, const QString code.rawAppendToCpp(u"// qmltc support library:"); code.rawAppendToCpp(u"#include <private/qqmlcppbinding_p.h>"); // QmltcSupportLib code.rawAppendToCpp(u"#include <private/qqmlcpponassignment_p.h>"); // QmltcSupportLib + code.rawAppendToHeader(u"#include <private/qqmlcpptypehelpers_p.h> "); // QmltcSupportLib code.rawAppendToCpp(u"#include <private/qqmlobjectcreator_p.h>"); // createComponent() code.rawAppendToCpp(u"#include <private/qqmlcomponent_p.h>"); // QQmlComponentPrivate::get() diff --git a/tools/qmltc/qmltccompiler.cpp b/tools/qmltc/qmltccompiler.cpp index a69f8619e9..4050136ef2 100644 --- a/tools/qmltc/qmltccompiler.cpp +++ b/tools/qmltc/qmltccompiler.cpp @@ -425,7 +425,24 @@ compileMethodParameters(const QList<QQmlJSMetaParameter> ¶meterInfos, bool a Q_ASSERT(allowUnnamed || !name.isEmpty()); // assume verified if (name.isEmpty() && allowUnnamed) name = u"unnamed_" + QString::number(i); - parameters.emplaceBack(p.type()->augmentedInternalName(), name, QString()); + + QString internalName; + const QQmlJSScope::AccessSemantics semantics = p.type()->accessSemantics(); + + switch (semantics) { + case QQmlJSScope::AccessSemantics::Reference: + if (p.typeQualifier() == QQmlJSMetaParameter::Const) + internalName = u"const "_s; + internalName += u"%1*"_s.arg(p.type()->internalName()); + break; + case QQmlJSScope::AccessSemantics::Value: + case QQmlJSScope::AccessSemantics::Sequence: + internalName = u"passByConstRefOrValue<%1>"_s.arg(p.type()->internalName()); + break; + case QQmlJSScope::AccessSemantics::None: + Q_ASSERT(false); // or maybe print an error message + } + parameters.emplaceBack(internalName, name, QString()); } return parameters; } @@ -1658,12 +1675,9 @@ void QmltcCompiler::compileScriptBinding(QmltcType ¤t, slotMethod.type = QQmlJSMetaMethod::Slot; current.functions << std::move(slotMethod); - current.setComplexBindings.body - << u"QObject::connect(" + This_signal + u", " - + QmltcCodeGenerator::wrap_qOverload( - slotParameters, u"&" + objectClassName_signal + u"::" + signalName) - + u", " + This_slot + u", &" + objectClassName_slot + u"::" + slotName - + u");"; + current.setComplexBindings.body << u"QObject::connect(" + This_signal + u", " + u"&" + + objectClassName_signal + u"::" + signalName + u", " + This_slot + u", &" + + objectClassName_slot + u"::" + slotName + u");"; }; switch (binding.scriptKind()) { |