Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Qobject_cast triggers an assertion on QML components [SOLVED]
Qt 6.11 is out! See what's new in the release blog

Qobject_cast triggers an assertion on QML components [SOLVED]

Scheduled Pinned Locked Moved QML and Qt Quick
5 Posts 3 Posters 3.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mjmvisser
    wrote on last edited by
    #1

    I'm using this code to iterate through the children of my custom object (C++, derived from QObject) and check for a certain type:

    @
    foreach (QObject *o, children()) {
    Foo f = qobject_cast<Foo>(o);
    if (f) {
    // do foo stuff with f
    }
    }
    @

    This works great as long as there are only C++ objects in children(). However, when I make a component that extends a "Foo", like this:

    @import FooLib 1.0

    Foo {
    ...
    }
    @

    qobject_cast<Foo *> triggers an assertion failure:

    @ASSERT: "!dp->isFunction()" in file qml/qqmlpropertycache.cpp, line 1509@

    Here's a stack trace:

    @148 raise() 0x0000003562a32885
    147 abort() 0x0000003562a34065
    146 qt_message_fatal() qlogging.cpp:806 0x00007ffff6758da9
    145 QMessageLogger::fatal() qlogging.cpp:355 0x00007ffff6756ffa
    144 qt_assert() qglobal.cpp:1951 0x00007ffff675233c
    143 QQmlPropertyCache::toMetaObjectBuilder() qqmlpropertycache.cpp:1509 0x00007ffff7c21db5
    142 QQmlPropertyCache::createMetaObject() qqmlpropertycache.cpp:528 0x00007ffff7c1dc69
    141 QQmlVMEMetaObject::toDynamicMetaObject() qqmlvmemetaobject.cpp:539 0x00007ffff7b66944
    140 QObjectData::dynamicMetaObject() qobject.cpp:189 0x00007ffff69732f4
    139 ShotgunEntity::metaObject() moc_shotgunentity.cpp:100 0x00007fffec20e16b
    138 QMetaObject::cast() qmetaobject.cpp:338 0x00007ffff6941eda
    137 qobject_cast<Property*>() qobject.h:451 0x00007fffec1d03b6
    136 NodeBase::inputs() nodebase.cpp:364 0x00007fffec1cf758 @

    Am I doing something wrong?

    thanks,
    -Mark

    1 Reply Last reply
    0
    • B Offline
      B Offline
      beemaster
      wrote on last edited by
      #2

      This is because your QML type is not "Foo". It's some internal type like QMLTYPE_123. You can check

      @
      Foo {
      id: object
      Component.onCompleted: console.log(object)
      }
      @

      My guess is that in QML, inheritance works differently, for example through composition.

      1 Reply Last reply
      0
      • T Offline
        T Offline
        ThomasHartmann
        wrote on last edited by
        #3

        This seems to be a bug in QML. The meta data from QML Components is stored in a structure called QQmlPropertyCache. The QMetaObject is then created on demand (In this case the qobject_cast).

        The creation of the QMetaObject seems to fail/assert in your case.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mjmvisser
          wrote on last edited by
          #4

          bq. My guess is that in QML, inheritance works differently, for example through composition.

          Good point, I think they're all internally instances of QQmlComponent or some such. I'll have to figure out a different way to check if a QObject conforms to a particular interface.

          bq. The QMetaObject is then created on demand (In this case the qobject_cast).

          Well, it tries to create the metaobject on demand, anyway. I'm not sure why, but QML component objects do not have an associated QMetaObject. I discovered this when trying to see how hard it would be to add support for native QML attached properties objects (answer: hard enough that I gave up).

          I'll whip up a small test case when I have a chance and file a bug report.

          So bug aside, anyone know how to check if a QML instance conforms to an interface?

          edit: I tried guarding the qobject_cast with
          @if (o->inherits("Foo"))@

          The qobject_cast still triggers an assertion for QML instances "derived" from Foo.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mjmvisser
            wrote on last edited by
            #5

            Solved!

            I figured it out after being unable to reproduce it in a simplified test case.

            The base class of Foo has a default property called "data", patterned after QQmlItem. I had forgotten this and added an invokable method, also called "data", to Foo. In concrete instances of Foo, this wasn't a problem because they had different method signatures, but as soon as I started using QML instances, the invokable clobbered the default property.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved