当光标移动到鼠标区域外时,按下光标保持其形状



我正在实现狭窄的调整手柄,这给了我恼人的行为。当鼠标直接在手柄上时,光标形状与预期一致,但是一旦开始拖动手柄,光标形状就会变得不一致。这有两个原因:

  • 当光标快速移动并在手柄前面移动直到手柄"赶上"时(或者当"流体qml"太流体时)-当光标形状快速变化并闪烁时,

  • 这尤其令人讨厌
  • 当光标移动到句柄允许的自由度之外时

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

我确实设法找到了一个hack来修复它-使用假覆盖MouseAreaacceptedButtons: Qt.NoButton -这实际上有助于伪造光标一致性,但有一个自己的问题。有了这个覆盖的鼠标区域,光标在手柄上方时不允许改变为可调整大小的形状,因为手柄在覆盖的鼠标区域下方,所以它根本无法修改光标形状。因此,只有在点击手柄后,调整大小形状才会生效,这远非理想状态。将鼠标覆盖区域设置为enabled: false不会改变这一点-它仍然会阻止光标形状从底层鼠标区域变化。也有一种解决方法,例如将覆盖的鼠标区域大小设置为0x0,但它有点难看。

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

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

我没有找到一种开箱即用的方法,但是为此创建一个帮助器非常容易。在qml端,你可以使用:

CursorChanger {
    cursor: Qt.SizeHorCursor
    active: dragArea.containsMouse || dragArea.drag.active
}
在c++端,你需要一个像这样的helper类:
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");`

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

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

相关内容

  • 没有找到相关文章

最新更新