QCustomPlot之設置鼠標形狀(十三)

默認只有QWidget才有setCursor接口,QCustomPlot也沒有為我們擴展它,所以我們自己增加可以設置鼠標形狀的接口

效果圖
void QCPLayerable::setCursor(const QCursor &cursor)
{
    mHasCursor = true;  // 新增的bool成員變量
    mCursor = cursor;    // 新增的QCursor成員變量
    if (mParentPlot && mParentPlot->underMouse()) {
        const auto layerableList = mParentPlot->layerableListAt(mParentPlot->mapFromGlobal(QCursor::pos()), false);
        for (auto *layerable : layerableList) {
            if (layerable->hasCursor()) {
                QMetaObject::invokeMethod(mParentPlot, "setViewportCursor",
                                          Q_ARG(QCursor, layerable->cursor()));
                break;
            }
        }
    }
}

void QCPLayerable::unsetCursor()
{
    if (!mHasCursor || !mParentPlot)
        return;

    mHasCursor = false;
    if (mParentPlot->underMouse() && mParentPlot->layerableAt(mParentPlot->mapFromGlobal(QCursor::pos()), false) == this) {
        QMetaObject::invokeMethod(mParentPlot, "unsetViewportCursor");
    }
}

同時為QCPLayerable新增鼠標進入和離開事件

virtual void hoverEnterEvent(QHoverEvent *event) { Q_UNUSED(event) }
virtual void hoverLeaveEvent(QHoverEvent *event) { Q_UNUSED(event) }

我們主要在QCustomPlot中的mouseMoveEvent事件中處理鼠標形狀的改變以及鼠標進入和離開QCPLayerable事件的傳遞

    event->accept();   // 以上為源碼內容

    auto list = layerableListAt(event->pos(), false);
    QCPLayerable *hoveredLayerable = list.isEmpty() ? nullptr : list.first();
    if (hoveredLayerable) {
        if (mLastHoverLayerable != hoveredLayerable) {
            if (mLastHoverLayerable) {
                auto *item = static_cast<QCPAbstractItem *>(mLastHoverLayerable);
                if (item) emit hoverLeaveItem(item);
                QHoverEvent hoverEvent(QEvent::HoverLeave, QPointF(-1, -1), event->pos(), event->modifiers());
                mLastHoverLayerable->hoverLeaveEvent(&hoverEvent);
            }

            mLastHoverLayerable = hoveredLayerable;
            auto *item = static_cast<QCPAbstractItem *>(mLastHoverLayerable);
            if (item) emit hoverEnterItem(item);
            QHoverEvent hoverEvent(QEvent::HoverEnter, event->pos(), QPointF(-1, -1), event->modifiers());
            mLastHoverLayerable->hoverEnterEvent(&hoverEvent);
        }
    }

    // 以后可以優(yōu)化
    foreach (auto *layerable, list) {
        if (layerable->hasCursor()) {
            setViewportCursor(layerable->cursor());
            return;
        }
    }

    if (mLastHoverLayerable) {
        auto *item = static_cast<QCPAbstractItem *>(mLastHoverLayerable);
        if (item) emit hoverLeaveItem(item);
        QHoverEvent hoverEvent(QEvent::HoverLeave, QPointF(-1, -1), event->pos(), event->modifiers());
        mLastHoverLayerable->hoverLeaveEvent(&hoverEvent);
        mLastHoverLayerable = nullptr;
    }

    if (mHasStoredOriginalCursor) {
        mHasStoredOriginalCursor = false;
        setCursor(mOriginalCursor);
    }

設置和恢復QCustomPlot的鼠標形狀,注意這兩個函數(shù)要聲明為Q_INVOKABLE

void QCustomPlot::setViewportCursor(const QCursor &newCursor)
{
    if (!mHasStoredOriginalCursor) {
        mHasStoredOriginalCursor = true;
        mOriginalCursor = cursor();
    }
    setCursor(newCursor);
}

void QCustomPlot::unsetViewportCursor()
{
    const auto layerableList = layerableListAt(mapFromGlobal(QCursor::pos()), false);
    foreach (auto *layerable, layerableList) {
        if (layerable->hasCursor()) {
            setViewportCursor(layerable->cursor());
            return;
        }
    }

    if (mHasStoredOriginalCursor) {
        mHasStoredOriginalCursor = false;
        setCursor(mOriginalCursor);
    }
}

我們可以通過設置setSelectionTolerance設置QCustomPlot的選擇誤差范圍來決定QCustomPlot的鼠標點擊(懸?。┬袨?/p>

注意要將QCPLayerable設置為QCustomPlot的友元類

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容