Qt 当光标移动到鼠标区域外时,按住光标形状

Qt 当光标移动到鼠标区域外时,按住光标形状,qt,cursor,qml,mousearea,Qt,Cursor,Qml,Mousearea,我正在实现狭窄的调整大小手柄,这会让我感到恼火。鼠标直接位于控制柄上时,光标形状与预期一致,但一旦启动拖动控制柄,光标形状将变得不一致。这有两个原因: 当光标快速移动并在手柄之前移动,直到手柄“赶上”(或当“fluid qml”过于流动时)-这尤其令人讨厌,因为光标形状会快速变化并闪烁 光标移动到控制柄允许的自由度之外时 我查阅了文档,但它似乎没有包含任何关于锁定光标的内容,直到按下按钮 我确实找到了一个黑客来修复它-使用一个虚拟覆盖MouseArea和acceptedButtons:Qt.

我正在实现狭窄的调整大小手柄,这会让我感到恼火。鼠标直接位于控制柄上时,光标形状与预期一致,但一旦启动拖动控制柄,光标形状将变得不一致。这有两个原因:

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

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

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

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

理想情况下,光标形状应该一直保持到按下鼠标区域为止,不管它是在它的区域内还是在它的区域外-毕竟,如果你走到它的外部,按下按钮不会被释放,因此鼠标区域仍然处于控制状态,并且应该保持它的光标形状。例如-窗口大小调整手柄保持大小调整形状,即使它被移动以将窗口大小调整为小于其最小大小,直到释放按键


在我看来,
MouseArea的实现似乎有缺陷——按下鼠标时光标形状不会保持不变,即使鼠标区域被禁用,光标形状也会改变。

我没有找到一种现成的方法,但是为它创建一个帮助器非常容易。在qml方面,例如,您可以:

CursorChanger {
    cursor: Qt.SizeHorCursor
    active: dragArea.containsMouse || dragArea.drag.active
}
在C++方面,你需要一个类似这样的助手类:

类游标转换器:公共QObject
{
Q_对象
Q_属性(bool active READ active WRITE setActive NOTIFY activeChanged)
Q_属性(int cursor READ cursor WRITE setCursor NOTIFY cursorChanged)
// ...
}
在实现中,您可以使用
QGuiApplication::setOverrideCursor
QGuiApplication::restoreOverrideCursor
来实际设置/重置光标。如果此时处于活动状态,请不要忘记在
游标或转换器中重置析构函数。如果随后注册类型:

qmlRegisterType(uri,1,0,“游标转换器”)`

您可以从qml使用这种类型。

我认为当前行为有一些用例。例如,光标可以在当前悬停的对象和按下鼠标的对象之间传递某种关系。另一个例子是,拖动可能会有意限制其速度,当用户速度过快时,结果取决于后面的项目

当然,dtech的需求更为普遍,我也希望将其视为一种可选功能,而不是一种改变。现在的方式为应用程序提供了更多的功能。我不喜欢那些只能完全按照库作者的想象使用的抛光组件

持久拖动光标的另一个仅适用于QML的解决方案是在所有iTen后面有一个鼠标earea,以便在需要时保持持久形状:

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;
        }
    }
}

按下时不保持光标形状这一事实似乎是故意的选择,QWidgets和QQuickItems在这方面有着相同的行为。只是好奇一下,您的用例是什么?问题的第一部分描述了它。此外,我并没有暗示这是“偶然的”,只是目光短浅,特别是在Qt和QML中,这远远不是唯一的例子。如果某个项目设置了光标,则只要该项目对光标具有控制权,而不仅仅是当光标位于其所在区域时,就应该应用该选项。禁用的项目不应干扰光标。这仅仅是合乎逻辑的。还有许多其他的例子说明了为什么这种行为是有意义的——例如旋转旋钮,这是通过上下或左右移动鼠标来实现的。您希望在旋转时保持光标保持其“旋转旋钮”形状,而不仅仅是当光标位于旋钮上方时。光标指示您正在做什么,不是严格地说,而是仅指示您所在的位置。在调整大小时需要一个调整大小的光标,在拖动时需要一个拖动光标,在移动时需要一个移动光标。就这么简单。确实如此:)我浏览了第一部分,对不起。