You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python2.7/PySide2:让QGraphicsPathItem可选中且不显示选中框

解决QGraphicsPathItem默认选中框问题,自定义选中边缘效果

首先得提个小细节:你不需要同时继承QGraphicsPathItemQGraphicsItem,因为QGraphicsPathItem本身就是QGraphicsItem的子类,多重继承在这里纯属多余,反而可能引入不必要的复杂度,直接继承QGraphicsPathItem就好。

接下来解决默认选中框的问题,核心思路是重写paint方法,接管选中状态的绘制逻辑,不让Qt绘制默认的虚线框,同时保留正常的选中交互功能。这里有两种靠谱的实现方式,你可以根据需求选:


方式一:完全自定义绘制逻辑

适合想完全掌控路径和选中效果绘制的场景,直接跳过父类的paint方法,自己绘制所有内容:

#include <QGraphicsPathItem>
#include <QPainter>

class CustomSelectablePath : public QGraphicsPathItem
{
public:
    CustomSelectablePath(QGraphicsItem* parent = nullptr) 
        : QGraphicsPathItem(parent)
    {
        // 开启选中功能,还可以按需添加可移动等其他标志
        setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
    }

protected:
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override
    {
        // 绘制正常状态的路径
        painter->setPen(pen());
        painter->setBrush(brush());
        painter->drawPath(path());

        // 如果处于选中状态,绘制自定义的选中边缘
        if (isSelected())
        {
            QPen selectedPen(Qt::darkBlue); // 自定义选中颜色
            selectedPen.setWidth(2); // 选中线宽
            selectedPen.setStyle(Qt::SolidLine); // 选中线样式(比如实线)
            painter->setPen(selectedPen);
            // 直接绘制路径作为选中边缘,或者可以绘制一个扩展的外边框
            // QPainterPath expandedPath = path();
            // expandedPath.adjust(-2, -2, 2, 2); // 向外扩展2像素
            // painter->drawPath(expandedPath);
            painter->drawPath(path());
        }
    }
};

方式二:复用父类绘制,仅屏蔽默认选中框

如果你想保留父类QGraphicsPathItem的默认绘制逻辑(比如路径的填充、线条样式),只需要去掉默认选中框,然后叠加自定义选中效果,可以用这种方式:

#include <QGraphicsPathItem>
#include <QPainter>
#include <QStyleOptionGraphicsItem>

class CustomSelectablePath : public QGraphicsPathItem
{
public:
    CustomSelectablePath(QGraphicsItem* parent = nullptr) 
        : QGraphicsPathItem(parent)
    {
        setFlags(QGraphicsItem::ItemIsSelectable);
    }

protected:
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override
    {
        // 复制原样式选项,去掉选中状态标记
        QStyleOptionGraphicsItem customOption = *option;
        customOption.state &= ~QStyle::State_Selected;

        // 调用父类paint,此时不会绘制默认选中框
        QGraphicsPathItem::paint(painter, &customOption, widget);

        // 叠加自定义选中效果
        if (isSelected())
        {
            QPen highlightPen(Qt::red);
            highlightPen.setWidth(3);
            highlightPen.setStyle(Qt::DashLine); // 用虚线作为选中边缘
            painter->setPen(highlightPen);
            painter->drawPath(path());
        }
    }
};

关键说明:

  • 确保ItemIsSelectable标志已开启:这是item能被选中的前提,不会因为重写paint而失效,选中交互逻辑由Qt的Graphics View框架负责,我们只改视觉表现。
  • 自定义选中效果可以灵活调整:比如颜色、线宽、线样式,甚至可以绘制阴影、渐变边框等,完全根据你的需求来。
  • 如果你需要调整选中区域的范围(比如让点击路径外一定区域也能选中),可以重写shape()方法,返回一个扩展后的路径,但这部分不是你的需求重点,就不多展开了。

内容的提问来源于stack exchange,提问作者Kevin

火山引擎 最新活动