3

我已经在 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 中找不到这样的功能。

4

1 回答 1

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 - 因为只有两个鼠标坐标之间的差异是感兴趣的,所以不需要将位置链接到窗口。在这种情况下,小部件将按预期在触摸屏和鼠标操作的屏幕上工作 - 无论光标相对于窗口框架如何定位,鼠标/手指的相同移动都会以相同的方式改变方向。

于 2013-04-25T14:29:25.873 回答