Skip to content

Commit

Permalink
qml: allow inline component types as signal argument
Browse files Browse the repository at this point in the history
The resolution of inline components through QQmlType was failing and
therefore inline components were not allowed as signal parameters.

Apply the same fix as 2a37ff2 to signal
parameter-type resolution.

Test if signals with inline-component-typed parameters works, even if
the inline component is defined in another qml file.

SignalInlineComponentArg.qml is capitalized as it is used in
signalInlineComponentArg1.qml.

Pick-to: 6.4 6.3 6.2
Fixes: QTBUG-106611
Change-Id: I2bbcee56025e6a319a3fea9b7aedf703afabe6b3
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
  • Loading branch information
samishalayel committed Sep 19, 2022
1 parent c506b71 commit 5780828
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/qml/qml/qqmlpropertycachecreator_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,15 @@ inline QMetaType QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter
QQmlType::AnyRegistrationType, &selfReference))
return QMetaType();

if (!qmltype.isComposite())
return qmltype.typeId();
if (!qmltype.isComposite()) {
const QMetaType typeId = qmltype.typeId();
if (!typeId.isValid() && qmltype.isInlineComponentType()) {
const int objectId = qmltype.inlineComponentId();
return objectContainer->typeIdsForComponent(objectId).id;
} else {
return typeId;
}
}

if (selfReference)
return objectContainer->typeIdsForComponent().id;
Expand Down
21 changes: 21 additions & 0 deletions tests/auto/qml/qqmllanguage/data/SignalInlineComponentArg.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import QtQuick

Item {
component Abc: Item {
property string success
}

signal canYouFeelIt(arg1: Abc)
property Abc someAbc: Abc {
success: "Signal was called"
}
property string success: "Signal not called yet"

Component.onCompleted: {
canYouFeelIt(someAbc);
}

onCanYouFeelIt: (arg) => {
success = arg.success
}
}
30 changes: 30 additions & 0 deletions tests/auto/qml/qqmllanguage/data/signalInlineComponentArg1.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import QtQuick

// this file performs two tests: first, using a signal with a inline component from another file
// and second, calling the signal from another file using an inline component from another file

Item {
signal canYouFeelIt(arg1:SignalInlineComponentArg.Abc)

property SignalInlineComponentArg.Abc someAbc: SignalInlineComponentArg.Abc {
success: "Own signal was called with component from another file"
}

property SignalInlineComponentArg fromAnotherFile: SignalInlineComponentArg {}

// success of own signal call with parameter from another file
property string successFromOwnSignal: "Signal not called yet"
// makes it easier to test
property string successFromSignalFromFile: fromAnotherFile.success

Component.onCompleted: {
canYouFeelIt(someAbc);
fromAnotherFile.someAbc.success = "Signal was called from another file"
fromAnotherFile.canYouFeelIt(fromAnotherFile.someAbc)
}

onCanYouFeelIt: (arg) => {
successFromOwnSignal = arg.success
}
}

23 changes: 23 additions & 0 deletions tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ private slots:
void bindingAliasToComponentUrl();
void badGroupedProperty();
void functionInGroupedProperty();
void signalInlineComponentArg();

private:
QQmlEngine engine;
Expand Down Expand Up @@ -7650,6 +7651,28 @@ void tst_qqmllanguage::functionInGroupedProperty()
.arg(url.toString()));
}

void tst_qqmllanguage::signalInlineComponentArg()
{
QQmlEngine engine;
{
QQmlComponent component(&engine, testFileUrl("SignalInlineComponentArg.qml"));
QVERIFY2(component.isReady(), qPrintable(component.errorString()));
QScopedPointer<QObject> object(component.create());

QCOMPARE(object->property("success"), u"Signal was called"_s);
}
{
QQmlComponent component(&engine, testFileUrl("signalInlineComponentArg1.qml"));
QVERIFY2(component.isReady(), qPrintable(component.errorString()));
QScopedPointer<QObject> object(component.create());

QCOMPARE(object->property("successFromOwnSignal"),
u"Own signal was called with component from another file"_s);
QCOMPARE(object->property("successFromSignalFromFile"),
u"Signal was called from another file"_s);
}
}

QTEST_MAIN(tst_qqmllanguage)

#include "tst_qqmllanguage.moc"

0 comments on commit 5780828

Please sign in to comment.