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

QMetaMethod::invoke: Support passing arguments constructed via QMetaType::create()

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.5.0 Beta1
    • Core: Object Model
    • None
    • All

    Description

      The typesafe QMetaMethod::invoke() API introduced in 6.5 is nice as long as all involved C++ are known by the caller. For script binding and testing purposes (i.e. Squish) however it may be necessary to entirely introspect types at runtime (via QMetaObject and QMetaType).

      Especially for gadget types it may be necessary to create or copy a gadget instance via void* QMetaType::create(void* copy = nullptr).
      Passing the returned void pointer is possible with the (now deprecated) QGenericArgument API. It does not appear to be possible with the new approach or at least not without delving into QtPrivate namespace members.

      Here's a complete example of how the old API worked with runtime introspected and created gadgets works (also attached as a zip including a qmake project to try it out):

      #include <QCoreApplication>
      #include <QDebug>
      #include <QMetaMethod>
      #include <QMetaType>
      #include <QObject>
      #include <cassert>
      
      class MyGadget {
          Q_GADGET
      public:
          void gogo()
          {
              qInfo() << Q_FUNC_INFO;
          }
      };
      
      class MyObject : public QObject {
          Q_OBJECT
      
      public:
          Q_INVOKABLE void gogoGadget(MyGadget gadget)
          {
              qInfo() << Q_FUNC_INFO;
              gadget.gogo();
          }
      };
      
      int main(int argc, char** argv)
      {
          QCoreApplication app(argc, argv);
          qRegisterMetaType<MyGadget>();
      
          const QMetaType gadgetType = QMetaType::fromName("MyGadget");
          void* gadgetInstance = gadgetType.create();
      
          MyObject obj;
          const int gogoMethodIndex = obj.metaObject()->indexOfMethod("gogoGadget(MyGadget)");
          const QMetaMethod gogoMethod = obj.metaObject()->method(gogoMethodIndex);
          gogoMethod.invoke(&obj, QGenericReturnArgument(), QGenericArgument("MyGadget", gadgetInstance));
      
          gadgetType.destroy(gadgetInstance);
      
          return 0;
      }
      
      #include "moc_metamethodinvoke.cpp"
      

      Attachments

        For Gerrit Dashboard: QTBUG-110316
        # Subject Branch Project Status CR V

        Activity

          People

            thiago Thiago Macieira
            stefgehn Stefan Gehn
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There is 1 open Gerrit change