美文网首页Qt
QCustomPlot之设置鼠标形状(十三)

QCustomPlot之设置鼠标形状(十三)

作者: 梁如风 | 来源:发表于2020-04-09 01:38 被阅读0次

    默认只有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);
            }
        }
    
        // 以后可以优化
        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的鼠标形状,注意这两个函数要声明为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的鼠标点击(悬浮)行为

    注意要将QCPLayerable设置为QCustomPlot的友元类

    相关文章

      网友评论

        本文标题:QCustomPlot之设置鼠标形状(十三)

        本文链接:https://www.haomeiwen.com/subject/mtgfmhtx.html