Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Dynamic object creation in Qt6
Forum Updated to NodeBB v4.3 + New Features

Dynamic object creation in Qt6

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 3 Posters 867 Views
  • 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.
  • A Offline
    A Offline
    aliks-os
    wrote on last edited by
    #1

    I want to create object of a class which inherited from QObject. The my following code work excelent in Qt5.

            int typeID = QMetaType::type(QString(deviceObject->type + "Device*").toLatin1());
            if (typeID != QMetaType::UnknownType)
            {
                const QMetaObject *mo = QMetaType::metaObjectForType(typeID);
                if (mo)
                {
                    QObject *objectPtr = mo->newInstance(Q_ARG(QObject*, nullptr));
                    device = static_cast<AbstractDevice*>(objectPtr);
                }
            }
    

    I try to migrate the above to Qt6 and prepared the following

            QMetaType metaType = QMetaType::fromName(QString(deviceObject->type + "Device*").toLatin1());
            if (metaType.isValid() && metaType.flags().testFlag(QMetaType::PointerToQObject))
            {
                void *instance = metaType.create();
                device = static_cast<AbstractDevice*>(instance);
            }
    

    Of course, I do registration

    Q_DECLARE_METATYPE(TestDevice*);
    qRegisterMetaType<TestDevice*>("TestDevice*");
    

    But looks a creation is wrong, as object is not valid. And I see on debuger is not enter into object's constructor.

    Please help me adapt my code to Qt6

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Not looked into the details but why do you now need QMetaType::create() instead QMetaObject::newInstance()?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      A 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        Not looked into the details but why do you now need QMetaType::create() instead QMetaObject::newInstance()?

        A Offline
        A Offline
        aliks-os
        wrote on last edited by
        #3

        @Christian-Ehrlicher
        Because newInstance is marked as depricated

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Where?
          https://doc.qt.io/qt-6/qmetaobject.html#newInstance-1

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          0
          • A Offline
            A Offline
            aliks-os
            wrote on last edited by
            #5

            here
            https://doc.qt.io/qt-6/qmetaobject-obsolete.html

            1 Reply Last reply
            0
            • A Offline
              A Offline
              aliks-os
              wrote on last edited by
              #6

              and compilator give warning as well

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #7

                That method was just replaced with a variadic. It's an implementation detail, once the deprecated function gets removed the new version of the method steps in seamlessly so you don't need to worry about it. The compiler gives warning because a non-template method is always preferred to a template one.
                You can try newInstance<QObject*>(nullptr); to force the template method to be used

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                A 1 Reply Last reply
                1
                • VRoninV VRonin

                  That method was just replaced with a variadic. It's an implementation detail, once the deprecated function gets removed the new version of the method steps in seamlessly so you don't need to worry about it. The compiler gives warning because a non-template method is always preferred to a template one.
                  You can try newInstance<QObject*>(nullptr); to force the template method to be used

                  A Offline
                  A Offline
                  aliks-os
                  wrote on last edited by
                  #8

                  @VRonin Oh, thanks for pointing. I will try the new implementation

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    aliks-os
                    wrote on last edited by VRonin
                    #9

                    I re-coded, but in my case newInstance returns nullptr

                    QMetaType metaType = QMetaType::fromName(QString("TestDevice*").toLatin1().constData());
                            if (metaType.isValid() && metaType.flags().testFlag(QMetaType::PointerToQObject))
                            {
                                const QMetaObject *mo = metaType.metaObject();   // Not sure about it - is that correct?
                                if (mo)
                                {
                                    QObject *objectPtr = mo->newInstance<TestDevice*>(nullptr);   // Returns nullptr
                                    auto device = static_cast<TestDevice*>(objectPtr);
                                    device->setObjectName("ttt");
                                }
                            }
                    
                    1 Reply Last reply
                    0
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #10

                      QObject *objectPtr = mo->newInstance<TestDevice*>(nullptr); // Returns nullptr

                      The template argument(s) should be the type of the argument(s) of the constructor.
                      if the constructor is TestDevice(QObject *parent) then the template should be mo->newInstance<QObject*>(nullptr);

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      A 1 Reply Last reply
                      1
                      • VRoninV VRonin

                        QObject *objectPtr = mo->newInstance<TestDevice*>(nullptr); // Returns nullptr

                        The template argument(s) should be the type of the argument(s) of the constructor.
                        if the constructor is TestDevice(QObject *parent) then the template should be mo->newInstance<QObject*>(nullptr);

                        A Offline
                        A Offline
                        aliks-os
                        wrote on last edited by
                        #11

                        @VRonin
                        yes constructor is TestDevice(QObject *parent)

                        not clear re mo->newInstance<QObject*>(nullptr);
                        Should here I indicate a class of argument? Not a creating class?

                        1 Reply Last reply
                        0
                        • VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #12

                          Just to make it clearer, imagine newInstance is:

                          template <class T>
                          QObject* newInstance(T arg){
                          return new TestDevice(arg);
                          }
                          

                          In your code you are calling newInstance<TestDevice*> so T is TestDevice*. Since TestDevice doesn't have a constructor TestDevice(TestDevice*) the compiler fails. T should be a QObject* because that's what the TestDevice constructor expects so the template argument should be QObject*

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          A 1 Reply Last reply
                          2
                          • VRoninV VRonin

                            Just to make it clearer, imagine newInstance is:

                            template <class T>
                            QObject* newInstance(T arg){
                            return new TestDevice(arg);
                            }
                            

                            In your code you are calling newInstance<TestDevice*> so T is TestDevice*. Since TestDevice doesn't have a constructor TestDevice(TestDevice*) the compiler fails. T should be a QObject* because that's what the TestDevice constructor expects so the template argument should be QObject*

                            A Offline
                            A Offline
                            aliks-os
                            wrote on last edited by
                            #13

                            @VRonin Many thanks! Now all works as should be. Latest version is

                                QMetaType metaType = QMetaType::fromName("TestDevice*");
                                if (metaType.isValid() && metaType.flags().testFlag(QMetaType::PointerToQObject))
                                {
                                    const QMetaObject* metaObject = metaType.metaObject();
                                    if (metaObject)
                                    {
                                        // Correctly use the type TestDevice* with newInstance
                                        QObject* objectPtr = metaObject->newInstance<QObject*>(nullptr); // Pass nullptr for the parent argument
                                        if (objectPtr)
                                        {
                                            auto device = static_cast<TestDevice*>(objectPtr);
                                            device->setObjectName("ttt");
                                            qDebug() << "Device created and object name set to:" << device->objectName() << device->metaObject()->className();
                                        }
                                        else
                                        {
                                            qWarning() << "Failed to create an instance using newInstance for type: TestDevice*";
                                        }
                                    }
                                    else
                                    {
                                        qWarning() << "MetaObject is null for type: TestDevice*";
                                    }
                                }
                                else
                                {
                                    qWarning() << "Invalid or unsupported type: TestDevice*";
                                }
                            
                            1 Reply Last reply
                            0
                            • A aliks-os has marked this topic as solved on

                            • Login

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