按住鼠标区域时

时间:2016-09-28 16:42:23

标签: qt cursor qml mousearea

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

  • 当光标快速移动并超过手柄时,直到手柄“#34”赶上" (当"流体qml"太流畅) - 当光标形状快速变化并闪烁时,这尤其令人讨厌

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

我抬起了文档,但似乎没有任何关于锁定光标的内容,直到释放印刷机。

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

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

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

2 个答案:

答案 0 :(得分: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 中使用这种类型。

答案 1 :(得分: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;
        }
    }
}