Сохраняйте форму курсора при нажатии, когда он выходит за пределы MouseArea

Я использую узкие маркеры изменения размера, которые меня раздражают. Форма курсора соответствует ожидаемой, когда мышь находится непосредственно над маркером, но как только перетаскивается ручка, форма курсора становится несогласованной. Есть две причины этого:

  • когда курсор движется быстро и идет впереди ручки, пока ручка не "догоняет" (или когда "жидкость qml" слишком жидкая) - это особенно неприятно, поскольку форма курсора быстро меняется и мигает

  • когда курсор перемещается за пределы разрешенной степени свободы для ручки

Я посмотрел документ, но в нем ничего не говорится о блокировке курсора, пока не будет нажата кнопка.

Мне удалось найти взломать, чтобы исправить это - используя пустышку MouseArea с acceptedButtons: Qt.NoButton - это фактически помогает имитировать согласованность курсора, но имеет собственную проблему. Наличие этой области мыши с наложением не позволяет курсору изменить форму, когда он находится над маркером, поскольку дескриптор находится под областью наложения мыши, он вообще не может изменять форму курсора. Таким образом, форма изменения размера вступает в силу только после нажатия на ручку, что далеко от идеала. Установка области наложения мыши на enabled: false не меняет это - он все еще продолжает блокировать изменения формы курсора из основных областей мыши. Для этого также есть обходной путь, например, установка размера области наложения мыши на 0x0, но это немного уродливо.

В идеале форма курсора должна сохраняться до тех пор, пока область мыши не будет нажата, независимо от того, находится она внутри или вне ее области - в конце концов, нажатие не отпускается, если вы выходите за ее пределы, таким образом, область мыши все еще находится под контролем и должен сохранить свою форму курсора. Например, дескрипторы изменения размера окна сохраняют форму изменения размера, даже если ее перемещать для изменения размера окна, меньшего, чем минимальный размер, до тех пор, пока не будет отпущена печать.

Мне кажется, что есть недостатки в реализации MouseArea - форма курсора не сохраняется при нажатии, а форма курсора изменяется, даже если область мыши отключена.

2 ответа

Я не нашел способ сделать это из коробки, хотя создать помощника для этого довольно легко. На стороне qml вы можете, например, иметь:

      CursorChanger {
    cursor: Qt.SizeHorCursor
    active: dragArea.containsMouse || dragArea.drag.active
}

На стороне C++ вам понадобится вспомогательный класс, подобный этому:

      class CursorChanger : public QObject
{
    Q_OBJECT

    Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
    Q_PROPERTY(int cursor READ cursor WRITE setCursor NOTIFY cursorChanged)
    
    // ...
}

В реализации вы можете использовать QGuiApplication::setOverrideCursor а также QGuiApplication::restoreOverrideCursorдля фактической установки / сброса курсора. Не забудьте также сбросить в CursorChangerдеструктор, если он активен в этот момент. Если вы затем зарегистрируете тип:

      qmlRegisterType<CursorChanger>(uri, 1, 0, "CursorChanger");`

Вы можете использовать этот тип из qml.

Я думаю, что для текущего поведения есть несколько вариантов использования. Например, курсор может передавать некоторую связь между объектом, на который в данный момент наведен курсор, и тем, на котором была нажата мышь. Другой пример, скорость перетаскивания может быть намеренно ограничена, и когда пользователь движется слишком быстро, последствия, зависящие от предмета позади.

Требования dtech, безусловно, более распространены, и я также хотел бы видеть это как дополнительную функцию, а не как изменение. То, как это происходит сейчас, предоставляет более универсальные части для приложений. Мне не нравятся отшлифованные компоненты, которые можно использовать только так, как предполагал автор библиотеки.

Еще одно решение QML для постоянного курсора перетаскивания - иметь MouseArea за всеми объектами для удержания постоянной формы при необходимости:

      Item
{
    id: main;    width: 800;  height: 600

    MouseArea{  id: shapeHolder;   anchors.fill: main  }
    property alias cursor:  shapeHolder.cursorShape    //for use from other .qml
    
    Rectangle
    {
        id: draggable;    width: 40;  height: 30;   color: "red"
        MouseArea
        {
            anchors.fill:  parent
            drag.target :  parent

            //set and unset a persistent cursor
            onPressed :  main.cursor =  Qt.DragMoveCursor;
            onReleased:  main.cursor =  Qt.ArrowCursor;    //QT default cursor

            //cursor on hover, except if a persistent cursor is set
            cursorShape :  
                main.cursor === Qt.ArrowCursor ?  Qt.OpenHandCursor : main.cursor;
        }
    }

    Rectangle
    {
        id: otherItem;    x: 100; y: 100; width: 80; height: 60;  color: "blue"
        MouseArea
        {
            anchors.fill:  parent

            //this item shows an IBeamCursor, unless a persistent cursor is set
            cursorShape :  
                main.cursor === Qt.ArrowCursor ?  Qt.IBeamCursor : main.cursor;
        }
    }
}
Другие вопросы по тегам