Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Language Bindings
  4. Dynamically call methods from a scripting engine using QMetaMethod and QVariant.
Forum Updated to NodeBB v4.3 + New Features

Dynamically call methods from a scripting engine using QMetaMethod and QVariant.

Scheduled Pinned Locked Moved Unsolved Language Bindings
1 Posts 1 Posters 556 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.
  • F Offline
    F Offline
    French Paragon
    wrote on last edited by
    #1

    Hi, I'm wrinting a python api for one of my app using pybind11 (which is the best choice for me, even if it is sometimes not easy to integrate it with some Qt paradigms).

    I want to let the programmer using my api to interact with a certain family of qobjects (the editable items) using the meta object system through python.

    For the properties it's easy. I just had to wrote a method to convert pybind11::handle to QVariant, treating the cases that matter for my software (strings, numbers and nested editable items) and vice versa.

    But for some use cases I need invokable methods (for examples creating a new nested editable item and getting back its attributed id). I found this thread that describe how we can cheat with QGenericReturnArgument, QGenericArgument and QVariant to invoke a method once we know its signature, have the corresponding QVariants converted from the corresponding pybind11::handle (provided in a tuple): Qt invoke method with QVariant.

    So I can write something like that:

    pybind11::object EditableItemWrapper::invokeMethod(std::string m_name, py::tuple args) {
         QMetaMethod m = getMeth(m_name); //simplified
    
         do_checks(); //see if arguments matches both in numbers and types.
    
         int narg = m.parameterCount();
    
         switch(narg) {
         case 0:
               //do the business here.
               void v = NULL;
               const char* name = QMetaType::type(QMetaType(m.returnType()).metaObject().className());
               QVariant retVal (m.returnType(), v);
    
               bool sucess = invokeMethod(wrapped_obj(), m_name.c_str(), QGenericReturnArgument(name, retVal.data());
         ....
         case n:
               //repeat cleverly for each n up to a reasonable maximal under Q_METAMETHOD_INVOKE_MAX_ARGS
               //use the same tric for input values, creating the appropritate QVariant and giving the data() ptr to QGenericArgument
         }
    }
    

    But, the doc says its discouraged to work like that... Why ? (For example there is this limitation on the number of parameters, but it's a needed evil, isn't it ?)

    Ideally I'd like to invoke my method given a name, A QVariantList as parameter and get back a QVariant and a status code as return, isn't there something to do it already ?

    And is there any other solution ? What do you think ?

    Thanks in advance for your answers.

    Laurent

    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