Python2.7/PySide2:让QGraphicsPathItem可选中且不显示选中框
解决QGraphicsPathItem默认选中框问题,自定义选中边缘效果
首先得提个小细节:你不需要同时继承QGraphicsPathItem和QGraphicsItem,因为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




