Important: Please read the Qt Code of Conduct -

QtContactAction serviceFramework and qml

  • Hi,

    I have implemented mi own Call action like the default sendMail example, into the service framework.
    I have test it from c++ with the test mobility module and everything work fine.
    The service is deployed and the qcontact can see the new action only if supported by the contact.

    Now I want to use that action from qml.
    I need to retreive for every contact the supported action list (for example with a listView) and I want to be able to perform a selected action.

    The problem is I don't know how to make it from the qml side.
    Well I retreive the service object with the qml service element, but what's the kind of the object and how it works?

    Thank you very much for help

  • If what you retrieve is a QObject which has Q_PROPERTYs and Q_INVOKABLE functions, those should be available from QML due to the meta object system. You may need to provide your own QObject which has invokables which allow interaction with the QContactAction (rather than attempting to interact with the action directly). Good luck!

  • Thank you very much, I think you give me the correct suggestion.
    .. but now I have the second problem.

    I'm bulding my own adapter, but, how I can pass the current qml contact list Item to my method?
    There's a way to implicit convert a qml contactact element to a QContact object class?
    I already can do it with basic types, but what about complex object like Contact element.

    How can I binding the two object?

    Thank you very much

  • Hi,

    Every QDeclarativeContact is a QObject-derived type with a "QContact contact() const" accessor. I assume you're getting the list of declarative contacts from a QDeclarativeContactModel? You should be able to call "contacts()" which returns a QDeclarativeListProperty<QDeclarativeContact> and then for each one of those, get the underlying QContact. In reality, you shouldn't need to do that as all of the data you need to display in a UI should be available from the QDeclarativeContact instance for the particular QContact.

    As for binding, that should be handled automatically (although you may have to sync to the model, etc).


  • Yeah, you are right

    but the trouble is that QDeclarativeContact isn't installed by default.

    Now I have decided to incapsulate another contactManager into the c++ adapter (to be syncronized the the qml main one).
    Not a performance solution at all, but I think a bit elegant than modifing the core monbility library.

    Maybe there is an option to install all the QDeclarative<Mobility> header at compile time, but I don't know.

    Do you have better suggestions then mine?

  • You should be able to retrieve them as QObjects, though. All of the methods are available (via QMetaObject::invokeMethod()) on the QObject*. This means that while the headers aren't available, you can still access the data.

    Something like:
    QContact c;
    QMetaObject::invokeMethod(passedInQObjectPtr, "contact", Q_RETURN_ARG(QContact, c));

    Should work.

  • Hi, thank you very much for your help

    This, solution sound pretty good, today I'll try it :)

    thank you a lot

  • Hi

    I'm trying now your's solution and it works very well,
    apart from the last part :P

    invokeMethod(...) return this error:
    QMetaObject::invokeMethod: No such method QDeclarativeContact::contact()

    I have noteiced that also with a qml Item Element and

    QMetaObject::invokeMethod(obj, "objectName", Q_RETURN_ARG(QString, s));

    I have the same error message
    QMetaObject::invokeMethod: No such method QDeclarativeItem::objectName()

    I'm missing something? maybe in the .pro file?

  • After a bit of investigation I have found that the only accessible method list from metaObject QDeclarativeContact is composed by

    @QMetaMethod::Signal destroyed(QObject*)
    QMetaMethod::Signal destroyed()
    QMetaMethod::Slot deleteLater()
    QMetaMethod::Slot _q_reregisterTimers(void*)
    QMetaMethod::Signal contactIdChanged()
    QMetaMethod::Signal managerChanged()
    QMetaMethod::Signal detailsChanged()
    QMetaMethod::Slot clearDetails()
    QMetaMethod::Slot save()
    QMetaMethod::Slot setModified()
    QMetaMethod::Method QDeclarativeContactDetail* detail(QVariant)
    QMetaMethod::Method QDeclarativeListProperty<QDeclarativeContactDetail> details(QVariant)
    QMetaMethod::Method bool removeDetail(QDeclarativeContactDetail*)
    QMetaMethod::Method bool addDetail(QDeclarativeContactDetail*)
    QMetaMethod::Signal __0() @

    I can invoke only the qml invokables method and not the contatc() one I need.

    I think I have to return to my previous solution with 2 parallel contacts manager. One for the qml side and one for the c++ side

    anyway thanks for the the help


  • Hrm, the data access methods aren't marked Q_INVOKABLE? That (to me) sounds like a bug. I might be wrong (it might be deliberately limited in order to separate C++ side from QML side, to avoid round-trip conversions instead of simply accessing the same QContactManager from C++ and QML directly) but it seems like something clients would want to do.

    Sorry that my advice was incorrect! I hope your parallel managers solution works as required.


Log in to reply