QGraphicsPixmapItem不响应鼠标的问题

在重构一个派生于QGraphicsPixmapItem的类, 重写了其重绘函数, 实际上就是废弃了利用QGraphicsPixmapItem自己的paint()行为, 改为自行实现了. 但是写完了之后发现功能都正常, 但是就是无法响应鼠标点击操作, 而在别处通过程序触发的select事件它依然能够正常响应和更新显示.

这个问题很令人迷惑, 仔细复查代码才注意到, 在重构的过程中, 我删除了setPixmap()的调用. 所以问题就清楚了. QGraphicsPixmapItem重载实现了boundingRect()shape()两个函数, 这两个函数的实现都是基于设置的QPixmap来进行的. 在重构时, 因为不使用它的重绘机制, 实际上是把它当作是QGraphicsItem来用, 只是因为修改基类影响到其他地方才没有动作.

问题修改就很容易了, 重载shape()就解决了:

1
2
3
4
5
6
7
8
QPainterPath ChromosomePixmapItem::shape() const
{
const int delta = 5;
QPainterPath path;
path.addRect(_impl->_draw_contour.boundingRect()
.adjusted(-delta,-delta,delta,delta));
return path;
}

新老构造函数的对比: 在老的creator中, 使用setPixmap()了, 而新的构造函数里面没有这一句. 就使得这个QGraphicsPixmapItem一直是一个空的Item. 但是我实现了boundingRect(), 但是没有实现shape().
手册上说shape()如果未定义, 会使用boundingRect(), 但是这句话可能不能全信.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ChromosomePixmapItem::ChromosomePixmapItem(const Chromosome &chromo, const cv::Mat &mitosis_image, const ChromShowParam &show_param, const ChromEnhanceParam &enhance_param)
: LayoutItem()
, _impl{new Implementation(chromo, mitosis_image, show_param, enhance_param)}
{
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemIsMovable, true);
#ifdef REFACT_CHROMITEM
// 新方案, Implementation之后,
loadRaw();
applyChange(makeChromImage(_impl->_chromo._rotateAngle, _impl->_draw_scale, _impl->_flip));
reload();
#else
// 老方案.
...
makeChromImage(chromo._image, chromo._rotateAngle, chromo._mirrored);
_impl->_draw_pixmap = _impl->_enhancedOri
.scaled(_impl->_enhancedOri.size()*_impl->_draw_scale
, Qt::AspectRatioMode::KeepAspectRatio
, Qt::TransformationMode::SmoothTransformation);
setPixmap(_impl->_draw_pixmap);
#endif
...
}

事后回顾,其实从QPixmapPixmapItem派生并不是一个很好的方法,看似省事,实际上反倒是依赖了黑盒的东西。还不如老老实实直接从QPixmapItem直接走方便。