Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-117773

qobject_cast and QObject::findChild does not work for custom QML types integrated from C++

    XMLWordPrintable

Details

    • Android, macOS

    Description

      I have installed version Qt 6.5.3 on Ubuntu with an additional Android package. I'm building and debugging an application on a desktop and cross-compiling it to a target Android device.

      My application includes the QML CppClasses plugin, which registers C++ classes as QML types:

      // myqmltype.h
      class MyQmlType : public QObject
      {
          Q_OBJECT
          QML_ELEMENT
          ...
      
      // myqmlcontroller.h
      class MyQmlController : public QObject
      {
          Q_OBJECT
          QML_ELEMENT
          QML_UNCREATABLE("MyQmlController type cannot be created")
          ...

      qmltypes file contains:

          ...
          Component {
              file: "myqmltype.h"
              name: "MyQmlType"
              accessSemantics: "reference"
              prototype: "QObject"
              exports: ["CppClasses/MyQmlType 1.0"]
              exportMetaObjectRevisions: [256]
          }
          Component {
              file: "myqmlcontroller.h"
              name: "MyQmlController"
              accessSemantics: "reference"
              prototype: "QObject"
              exports: ["CppClasses/MyQmlController 1.0"]
              isCreatable: false
              exportMetaObjectRevisions: [256]
          }
          ...

      The problematic QML file looks like this:

      // MyComponent.qml
      import QtQuick
      
      import CppClasses as CPP
      
      Item {
          id: _control
      
          required property CPP.MyQmlController controller
      
          CPP.MyQmlType {
              id: _child
              anyProperty: controller.anyProperty // for example
          }
      }

      This component is perfect from a qmllint point of view, there are no `unqualified access` warnings. But I have two problems.

      In the application the component is created as follows:

      QVariantMap MyQmlController::defaultInitialProperties() const
      {
          QVariantMap initialProperties;
          initialProperties["controller"] = QVariant::fromValue(this);
          return initialProperties;
      }
      
      void MyQmlController::appendComponentWithInitialProperties(
          const QUrl &source, QQmlEngine *engine)
      {
          QQmlComponent component(engine, source, QQmlComponent::PreferSynchronous);
      
         auto item
              = qobject_cast<QQuickItem *>(component.createWithInitialProperties(defaultInitialProperties())); // [1]
      
          if (item) {
              auto child = item->findChild<MyQmlType *>("", Qt::FindDirectChildrenOnly); // [2]
          }
      }
      1. Line [1] shows a warning "Could not set initial property controller".
      2. In line [2] the variable child is always nullptr.

      On Ubuntu (gcc_64) there are no such problems and everything works correctly. We managed to find out that everything magically depends on whether QT_BOOTSTRAPPED is enabled or not.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qtqmlteam Qt Qml Team User
            maksimshapovalov Maksim Shapovalov
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes