Qt鼠标控制触摸和非触摸设备上的旋转

时间:2013-04-25 13:13:38

标签: c++ qt user-interface touch

我在Qt中实现了旋转小部件。当用户点击旋转时,鼠标光标被隐藏,向左/向下拖动鼠标逆时针旋转旋转,向右/向上拖动鼠标顺时针旋转旋转。释放鼠标时,鼠标光标设置为单击的原始位置。像这样实现:

void RotaryWidget::mousePressEvent(QMouseEvent *MouseEvent)
{
    mMousePos = QCursor::pos();
    mPreviousPos = MouseEvent->pos();
    setCursor(Qt::BlankCursor);
}

void RotaryWidget::mouseReleaseEvent(QMouseEvent *MouseEvent)
{
    QCursor::setPos(mMousePos);
    unsetCursor();
}

void RotaryWidget::mouseMoveEvent(QMouseEvent *MouseEvent)
{
    QPoint DeltaPos = MouseEvent->pos() - mPreviousPos;
    // Use DeltaPos to move my rotary
    mPreviousPos = MouseEvent->pos();
}

这样做的好处是,当连续存在多个旋转时,用户可以更快地进行调整。

上述代码存在错误,因为如果光标到达屏幕边缘,则无法移动鼠标,因此旋转不会移动。但是,用户无法看到光标,因此这是一个问题。我更改了mouseMoveEvent来修复它:

void RotaryWidget::mouseMoveEvent(QMouseEvent *MouseEvent)
{
    if(MouseEvent->globalPos() == mMousePos)
    {
        mPreviousPos = mapFromGlobal(mMousePos);
        return;
    }
    else
    {
        QCursor::setPos(mMousePos);
    }
    QPoint DeltaPos = MouseEvent->pos() - mPreviousPos;
    // Use DeltaPos to move my rotary
    mPreviousPos = MouseEvent->pos();
}

基本上,每次移动鼠标时,都会计算更改,然后将光标设置回原始按下位置(因此它永远不会离开屏幕)。顶部的if确保我们不会一遍又一遍地将鼠标位置连续设置到原始位置。

这适用于非触摸屏设备,但在触摸屏设备上,QCursor::setPos()不起作用,因为我无法以编程方式在屏幕上设置手指的位置!

我没有想到满足我所描述的所有要求的解决方案。如果有办法检测用户是否使用触摸屏,则可以修复,但我在Qt中找不到这样的功能。

1 个答案:

答案 0 :(得分:0)

您可以检查鼠标是在边缘还是在边缘之外,而不是尝试将鼠标强制到点击位置,如果是,则使用delta的恒定增量(最后一次移动):

void RotaryWidget::mouseMoveEvent(QMouseEvent *MouseEvent)
{
    QPoint DeltaPos;
    if(!isInsideWindow(MouseEvent))
    {
       DeltaPos = mPrevDeltaPos;
    }
    else
    {
       DeltaPos = MouseEvent->pos() - mPreviousPos;
       mPrevDeltaPos = DeltaPos;
       // Use DeltaPos to move my rotary
       mPreviousPos = MouseEvent->pos();
     }
}

修改

另一种选择是基于全局鼠标坐标而不是相对于窗口0的局部坐标来计算DeltaPos - 因为只感兴趣两个鼠标坐标之间的差异,所以位置不需要链接到窗口。在这种情况下,小部件可以按照预期用于触摸和鼠标操作屏幕 - 无论光标相对于窗口框架如何定位,鼠标/手指的相同移动将以相同方式改变方向。