5

我正在实现狭窄的调整大小句柄,这给我带来了烦人的行为。当鼠标直接位于手柄上方时,光标形状与预期一致,但一旦开始拖动手柄,光标形状就会变得不一致。造成这种情况的原因有两个:

  • 当光标快速移动并在手柄之前移动直到手柄“赶上”(或者当“fluid qml”过于流畅时) - 这尤其令人讨厌,因为光标形状会迅速变化并闪烁

  • 当光标移动到手柄允许的自由度之外时

我查阅了文档,但它似乎没有包含任何关于锁定光标的内容,直到按下释放。

我确实设法找到了修复它的方法 - 使用虚拟覆盖MouseArea-acceptedButtons: Qt.NoButton这实际上有助于伪造光标一致性,但也有其自身的问题。拥有该覆盖鼠标区域不允许光标在手柄上方时更改为调整大小形状,因为手柄位于覆盖鼠标区域下方,因此根本无法修改光标形状。因此,仅在单击手柄后才开始调整大小形状,这远非理想。将覆盖鼠标区域设置为enabled: false不会改变这一点 - 它仍然会阻止来自底层鼠标区域的光标形状变化。也有一个解决方法,例如将覆盖鼠标区域大小设置为 0x0,但它有点难看。

理想情况下,光标形状应该一直持续到鼠标区域被按下,无论它是在其区域内还是在其区域外 - 毕竟,如果您离开它,则不会释放按下,因此鼠标区域仍然处于控制之中并且应该保持其光标形状。例如 - 窗口调整大小手柄保持调整大小形状,即使它被移动以调整窗口大小小于其最小尺寸,直到按下释放。

对我来说,执行中似乎存在缺陷MouseArea- 按下时不会保持光标形状,即使禁用鼠标区域也会改变光标形状。

4

2 回答 2

0

我没有找到开箱即用的方法,但是为此创建一个助手非常容易。在 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::setOverrideCursorQGuiApplication::restoreOverrideCursor实际设置/重置光标。CursorChanger如果此时处于活动状态,请不要忘记在析构函数中重置。如果您随后注册类型:

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

你可以在 qml 中使用这种类型。

于 2021-05-07T15:21:47.340 回答
0

我认为当前行为有一些用例。例如,光标可以传达当前悬停对象与按下鼠标的对象之间的某种关系。另一个例子,拖拽可能会故意限制它的速度,当用户走得太快时,结果取决于后面的项目。

dtech 的需求肯定更普遍,我也希望将其视为可选功能,而不是更改。它现在的方式为应用程序提供了更多功能。我不喜欢只能完全按照图书馆作者想象的方式使用的抛光组件。

另一个用于持久拖动光标的 QML 唯一解决方案是在所有元素后面有一个 MouseArea 以在需要时保持持久形状:

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

    MouseArea
    {  
        id: mouse
        anchors.fill: scene
    }

    Rectangle
    {
        id: draggable;    width: 40;  height: 30;   color: "red"
        MouseArea
        {
            anchors.fill:  draggable
            drag.target :  draggable

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

            //let non default scene cursors prevail over the item's
            cursorShape: mouse.cursorShape === Qt.ArrowCursor ?  
                Qt.OpenHandCursor : mouse.cursorShape;
        }
    }
}
于 2021-06-12T01:16:04.767 回答