qml: allow inline component types as signal argument

The resolution of inline components through QQmlType was failing and
therefore inline components were not allowed as signal parameters.

Apply the same fix as 2a37ff2f49 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>
This commit is contained in:
Sami Shalayel 2022-09-14 11:23:10 +02:00
parent c506b7182f
commit 57808284db
4 changed files with 83 additions and 2 deletions

View File

@ -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;

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -397,6 +397,7 @@ private slots:
void bindingAliasToComponentUrl();
void badGroupedProperty();
void functionInGroupedProperty();
void signalInlineComponentArg();
private:
QQmlEngine engine;
@ -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"