前面我们开始提到了GraphicView的使用,也提到GraphicsItem的使用,并且开始了自定义GraphicsItem的编写,而且上次我们的GraphicsItem也是可以拖动了,但这离我们需要的效果还有一定的距离。
所以,这次,我们进一步优化它,主要在这两个方面
1、选择样式
我们想在鼠标选择的时候不显示那个虚线框,而是我们自定义的其他样式,比如点选的时候带黄色蒙版的样式。如下图效果:
很明显,我们可以看到自定义的myitem选中后的样式已经明显与众不同了。如何做到呢?上代码:
void buttonGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
Q_UNUSED(widget)
QStyleOptionGraphicsItem op;
painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
QRectF recf=boundingRect();
QRectF board=QRectF(0,-2,120,40);
QPen pen(Qt::red);
QColor clr=QColor(Qt::blue);
clr.setAlpha(20);
QBrush brush(clr);
painter->setPen(pen);
painter->setBrush(brush);
painter->drawRoundedRect(board,10,10);
painter->setPen(QPen(Qt::black));
if(!m_title.isEmpty())
painter->drawText(QPointF(board.center().rx()-16,board.center().ry()+4),m_title);
// 选中时绘制
if (option->state & QStyle::State_Selected) {
qreal itemPenWidth = pen.widthF();
const qreal pad = itemPenWidth / 2;
// 绘制实线
painter->setPen(Qt::NoPen);//QPen(color, penWidth, Qt::SolidLine)
painter->setBrush(Qt::NoBrush);
painter->drawRect(recf.adjusted(pad, pad, -pad, -pad));
//绘制透明遮盖层
QColor clor=QColor(Qt::yellow);
clor.setAlpha(25);
QBrush brusher(clor);
painter->setBrush(brusher);
painter->drawRect(recf.adjusted(pad, pad, -pad, -pad));
}
}
其实只需要在我们已经定义好的graphicsitems中重写paint。在里面按照boundingRect()的大小来绘制一个透明度小于100的rect即可。
这里要注意,item的正常显示的图形是比boundingRect()要小,这个量是要预留出来的。我这里的board就是比boundingRect()内缩了20个单位的item绘图区域。
2、文字输入
我们如果想让我们的items都有文字输入功能怎么办呢?在上面的代码中我们已经看到了绘制文字的语句,关键是如何接受到外面来的文字:
painter->setPen(QPen(Qt::black));
if(!m_title.isEmpty())
painter->drawText(QPointF(board.center().rx()-16,board.center().ry()+4),m_title);
我的思路是这样的,也许你们会有更好的思路,首先实现item的mouseclick 通过doubleclick,双击后捕获它,弹出对话框修改它。(当然,你也可以将文字修改问graphicsTextitems,通过焦点捕获来实现,看起来更直观,这个在后面的博文中会有这种实现方式),我们来看看效果:
关键代码(重写双击函数):
void buttonGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event){
bool ok;
QString strlabel=QInputDialog::getText(nullptr,"input label","please input the label text:",QLineEdit::Normal,"myItem",&ok);
if (ok && !strlabel.isEmpty())
m_title =strlabel;
QGraphicsItem::mouseDoubleClickEvent(event);
}
这里的m_tiltle是在头文件中声明的一个存储label的变量。
接下来,我们可能会有更多的需求,比如做一个简单的组态软件,我们后面可能就用用到GraphicsScene了,下篇博文我们就会从了解它开始。