Connecting a slot to a QSharedPointer (QQuickItem::grabToImage)



  • What I'm doing:
    I am trying to use the QQuickItem::grabToImage (http://doc.qt.io/qt-5/qquickitem.html#grabToImage) method to convert a Qt Quick Item to an image and in the documentation it says the QQuickItemGrabResult will emit the ready signal when grab has been completed. The issue I'm having is the QQuickItem::grabToImage returns a QSharedPointer and I can't find a "proper" way to connect a slot to a signal of a QSharedPointer. I know you can use QSharedPointer.data() to get the raw pointer, but why even return a QSharedPointer?

    What I need to know:
    What is the "proper" way to connect a slot to a signal of a QSharedPointer?


  • Lifetime Qt Champion

    Hi,

    You connect the object that is contained with the QSharedPointer not the QSharedPointer itself



  • Thanks for the response.

    If you're suppose to use the object that is contained then why even have it be a QSharedPointer in the first place. I see a couple flaws with the design:

    1. QQuickItem::grabToImage returns a QSharedPointer<QQuickItemGrabResult>, but in order to know when the QQuickItemGrabResult is ready you need to listen for a signal and QSharedPointers doesn't support signals.
    2. Connecting for a ready signal after making the request may result in never receiving the ready signal. This will happen if the request is really quick. I have tried using this design patter for creating asynchronous sql queries and I did miss the signal sometimes.

    Proposed Change:
    Have the class making the request create a QQuickItemGrabResult pointer itself, set all the dependencies, connect to all of its signals and then start the request. The requester class should also be in charge of managing the memory of the pointer it created.

    QQuickItemGragResult *result = new QQuickItemGragResult(item); //item is the QQuickItem to create an image out of
    connect(result, SIGNAL(ready()), this, SLOT(onReady()));
    result->start();

    ...

    void onReady() {
    QObject *sender = sender();
    ...
    sender->deleteLater();
    }


  • Lifetime Qt Champion

    It's just a matter of calling:

    connect(grabResult.data(), &QQuickItemGrabResult::ready, this, &MyClass::mySlot);

    I haven't checked the current implementation but in any case it's a costly operation so using a shared object might also be a non-negligeable resource usage improvement.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.