QGraphicsItem画空心图形

用QGraphicsItem类族画出的图形通常都是一个区域(实心的),比如画个圆或者画个矩形。那如果想画个矩形框或者圆形框呢?可以用如下方法,直接上代码

头文件

#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QGraphicsPathItem>
#include <QGraphicsEllipseItem>

namespace Ui {
class Widget;
}

class MyRectItem : public QGraphicsRectItem
{
public:
    MyRectItem(const QRectF &rect, QGraphicsItem *parent = 0);
    MyRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    QPainterPath shape() const;

protected:
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);

private:
    bool isHovered;
};

class MyEllipseItem : public QGraphicsEllipseItem
{
public:
    MyEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0);
    MyEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    QPainterPath shape() const;

protected:
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);

private:
    bool isHovered;
    QRectF rect;
};

源文件

#include <QPainterPath>
#include <QPainterPathStroker>

MyRectItem::MyRectItem(const QRectF &rect, QGraphicsItem *parent)
    : QGraphicsRectItem(rect, parent)
{
    this->isHovered = false;
    setFlag(QGraphicsItem::ItemIsSelectable);
    setAcceptHoverEvents(true);
}

MyRectItem::MyRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
    : QGraphicsRectItem(x, y, w, h, parent)
{
    this->isHovered = false;
    setFlag(QGraphicsItem::ItemIsSelectable);
    setAcceptHoverEvents(true);
}

void MyRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen;
    if (this->isSelected())
    {
        pen.setColor(Qt::red);
    }
    else
    {
        pen.setColor(Qt::green);
    }
    if (this->isHovered)
    {
        pen.setWidth(4);
    }
    else
    {
        pen.setWidth(2);
    }
    painter->setPen(pen);
    painter->drawRect(this->boundingRect());
}

QPainterPath MyRectItem::shape() const
{
    QPainterPath temp;
    temp.addRect(this->boundingRect());
    QPainterPathStroker pathStroker;

    QPainterPath path = pathStroker.createStroke(temp);
    return path;
}

void MyRectItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    this->isHovered = true;
    prepareGeometryChange();
}

void MyRectItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    this->isHovered = false;
    prepareGeometryChange();
}

MyEllipseItem::MyEllipseItem(const QRectF &rect, QGraphicsItem *parent)
    : QGraphicsEllipseItem(rect, parent)
{
    this->isHovered = false;
    setFlag(QGraphicsItem::ItemIsSelectable);
    setAcceptHoverEvents(true);
    this->rect = rect;
}

MyEllipseItem::MyEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
    : QGraphicsEllipseItem(x, y, w, h, parent)
{
    this->isHovered = false;
    setFlag(QGraphicsItem::ItemIsSelectable);
    setAcceptHoverEvents(true);
    this->rect.setX(x);
    this->rect.setY(y);
    this->rect.setWidth(w);
    this->rect.setHeight(h);
}

QRectF MyEllipseItem::boundingRect() const
{
    return this->rect;
}

void MyEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen;
    if (this->isSelected())
    {
        pen.setColor(Qt::red);
    }
    else
    {
        pen.setColor(Qt::green);
    }
    if (this->isHovered)
    {
        pen.setWidth(4);
    }
    else
    {
        pen.setWidth(2);
    }
    painter->setPen(pen);
    painter->drawEllipse(this->rect);
}

QPainterPath MyEllipseItem::shape() const
{
    QPainterPath temp;
    temp.addEllipse(this->boundingRect());
    QPainterPathStroker pathStroker;

    QPainterPath path = pathStroker.createStroke(temp);
    return path;
}

void MyEllipseItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    this->isHovered = true;
    prepareGeometryChange();
}

void MyEllipseItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    this->isHovered = false;
    prepareGeometryChange();
}

程序中包括一个矩形类和一个椭圆形类,选中会变色,悬停会变粗。

通过实现shape函数,使用QPainterPathStroker来画图形的外框,这样画出的图像就是空心的。

 

测试代码:

在scene上添加图形:

MyRectItem *itemRect = new MyRectItem(10, 10, 100, 100);
scene->addItem(itemRect);
MyRectItem *item2 = new MyRectItem( 20, 20, 120, 120);
scene->addItem(item2);

MyEllipseItem *item3 = new MyEllipseItem(30, 30, 50, 50);
scene->addItem(item3);

MyEllipseItem *item4 = new MyEllipseItem(50, 50, 100, 80);
scene->addItem(item4);

如图所示,鼠标划过时,框内图形可以选中也可以点击。

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值