How to make a MouseArea not react on transparent area of an Image



  • Dear all,
    I have an Image that it's a donut, and I would like to add a MouseArea that react only when the donut is touched and not react when the touch happens inside the hole (because there is another object in the hole with its MouseArea).
    How is it possible with QML ??

    Thanks,
    Gianluca.



  • This should be possible by using a custom QQuickItem which overrides the mouseEvent functions. Use the alpha channel of the image to decide if the mouse event gets accepted or not.

    Downside is that there is no way to get to the image through public API, so you would have to simply load it in your custom MouseArea.



  • [quote author="sletta" date="1413748267"]
    Downside is that there is no way to get to the image through public API, so you would have to simply load it in your custom MouseArea.[/quote]

    I have an idea to do this. Get the "visual parent":http://qt-project.org/doc/qt-5/qquickitem.html#parent-prop of your custom MouseArea in your case the image.
    @
    QImage image = parentItem()->window()->grabWindow();
    @
    Now you have an image of your image and can read the alpha of the clicked position.
    In qml can look like this:
    @
    Image {
    ...
    AlphaMouseArea {
    ...
    }
    }
    @

    It's a draft need some performance tweaks like don't grab the image every time if you click on it.



  • QQuickItem does not have a grabWindow() function. QQuickWindow has but that will include the background of the window and will thus most likely be fully opaque. In Qt 5.4, there is a requestGrab() function, but it is asynchronous and implies going to the render thread to render a copy, then reading that back, with a lag of one frame at the least, and potentially disrupting rendering because of the pixel readback.

    I'd do it the simple way:

    @
    class AlphaMouseArea : public QQuickItem {
    ...
    QImage mask;
    }

    Somewhere in AlphaMouseArea:
    mask = QImage("mask.png");

    in mouseEvent handlers:
    if (qAlpha(mask.pixel(mousePos)) > 0)
    accept
    else
    not accept
    @

    If you know it is going to always be a torus, solve the torus function in the mouse handler and save the extra cost of the image :)



  • [quote author="sletta" date="1413793658"]QQuickItem does not have a grabWindow() function. [/quote]

    Right, sorry my source is wrong i forgot the window().
    @
    QImage image = parentItem()->window()->grabWindow();
    @



  • As I pointed out, grabWindow will include the window itself and will thus most likely be opaque and therefore not useful for the purpose of an AlphaMouseArea.


Log in to reply
 

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