MouseArea cursorShape with a custom BitmapCursor



  • Is there any way to set a custom BitmapCursor to a MouseArea ?
    From the MouseArea doc only the predefined cursor shapes are available.
    Something like :

     MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.AllButtons
        hoverEnabled: true
        cursorShape: Qt.BitmapCursor("qrc:/skin/cursor_rotate")
    }
    


  • There is no built-in way to change cursor, but you can use quick-private module and override MouseArea. Add QT += quick-private to your *.pro file.
    Create CustomMouseArea class:

    #include <QPixmap>
    #include <QCursor>
    #include <QtQuick/private/qquickmousearea_p.h>
    
    class CustomMouseArea : public QQuickMouseArea
    {
        Q_OBJECT
    public:
        explicit CustomMouseArea(QQuickItem* parent = nullptr) : QQuickMouseArea(parent) {}
    
    public slots:
        void setBitmapCursor(const QString& path) {
            QPixmap p(path);
            QCursor c(p);
            setCursor(c);
        }
    };
    

    Register it as QML type in main.cpp before qml file loaded to engine:

    qmlRegisterType<CustomMouseArea>("Test", 1, 0, "CustomMouseArea");
    

    Use in in QML:

    ...
    import Test 1.0
    ...
        CustomMouseArea {
            anchors.fill: parent
    
            Component.onCompleted: setBitmapCursor(":/images/cur1.png")
        }
    

    This is just a simple examle, better way to use Q_PROPERTY.



  • Thanks a lot for your reply. It worked on a test qml project using .pro. But for my main project I'm using cmake, and I haven't found a proper way to have the header available..



  • Should be something like:

    include_directories (${Qt5Quick_PRIVATE_INCLUDE_DIRS})
    

  • Qt Champions 2018

    This can be done without private headers too, with a helper object as standalone or attached object just calling setCursor on the MouseArea.

    It could look like this on the QML Side

    MouseArea {
        Cursor.customPath: "qrc:/skin/cursor_rotate"
    }
    


  • Thanks @IntruderExcluder your solution is working fine. But of course I would rather not inherit a private class. @GrecKo can you be more precise ? I don't see how I could set a cursor in a MouseArea from an helperObject.. There is no Cursor property in the MouseArea so even with my helper object built (inheriting a QQuickItem) I don't know how to call it from within the mouseArea..



  • As a superfast solution you can create a custom class which extends QQuickItem:

    class ParentCursorChanger : public QQuickItem
    {
        Q_OBJECT
    public:
        explicit ParentCursorChanger(QQuickItem* parent = nullptr) : QQuickItem(parent) {}
    
    public slots:
        void setBitmapCursor(const QString& path) {
            QPixmap p(path);
            QCursor c(p);
            qobject_cast<QQuickItem*>(parent())->setCursor(c);
        }
    };
    

    Register it the same way as I posted before and do something like this in QML:

    MouseArea {
        anchors.fill: parent
        
       CursorChanger {
            Component.onCompleted: setBitmapCursor(":/images/cur1.png")
        }
    }
    

    But the super true way would be using attached properties ofcourse.


Log in to reply