基于Qt Graphics View Framework的画图软件的实现思路

1 篇文章 0 订阅

最近使用Qt开发了一个绘图软件,实现了拖动和放缩的功能。这里大体描述一下思路:

1、自定义类继承图形项:

    class MyItem : public QGraphicsItem

重写以下方法

    QRectF boundingRect()const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QPainterPath shape()const;

重写以下鼠标事件

    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);

2、自定义类继承视图:

    class MyView : public QGraphicsView 

重写以下事件

    //void paintEvent(QPaintEvent *pEvent);
    void mousePressEvent(QMouseEvent *mEvent);
    void mouseMoveEvent(QMouseEvent *mEvent);
    void mouseReleaseEvent(QMouseEvent *mEvent);

3、值得注意的地方:

(1)绘制放缩时候出现的皮筋效果:其实就是用虚线画出图形的外接矩形,为了区分图形是画好了,还是正在绘制中,可以加一个bool标记

(2)拖动和放缩:判断鼠标位置,在外接矩形边界上可以放缩,在矩形内部可以拖动,可以改变鼠标形状表现出来,也需要一个bool标记

(3)事件传递机制:由于视图和图形项都重写了鼠标事件,就会有一个问题,鼠标拖动等事件先从视图获得,然后传递到图形项,使用一个全局变量标记,这样

就不会出现图形项拖动带动视图中绘出内容

(4)坐标系的变换:在视图中绘制的图形坐标要变换到场景中去,由场景去负责图形项的管理,否则拖动的时候绘图会显示错位

(5)随笔画:继承item,写鼠标事件的时候,要注意判断点的位置,不能保证第一个点就在第二个点的左上方


目前界面大致如下:比较简单,菜单栏懒的写,工具栏只加了删除Action


目前实现的功能如下:

可以通过选择图形,然后在画布上拖动鼠标绘制简单几何图形,比如:直线,椭圆,矩形,一般四边形,五边形,六边形;

可以选中图形,进行移动;

可以通过图形四边进行放缩;

可以删除选中的图形,可以清空整个画布;

可以随笔涂鸦,画任何曲线,写字;

可以更换画笔的类型和大小;

可以更改画笔和填充颜色。


目前存在的问题如下:

程序结构不合理,把scene放在view里面,作为成员变量,明显不科学;view里面控制item的加减不符合实际。

更好的思路是自定义一个类继承QWidget,作为QMainWindow的中央控件,然后把scene和view都放进去。

继承view,重写view的事件不合理,最后重写widget的鼠标事件。

继承item,本身合理,但是应该把图形的属性分开单独设计图形类,然后把图形对象作为成员,沟通view和item的思路不合理,要用信号和槽。

删除有一个bug,那就是删除所有的item以后,再次添加会不显示,没有调试,虽然现在使用hack的方式解决了,但是习惯不好,不合理。


所犯过的低级错误:

以为写view的paint事件就能在view上显示,太天真,view显示的东西还是item绘制的,view只是一个媒介。

有人把scene比喻成黑板,item比如在黑板上画的图形或者写的字,而view呢,只相当于一个照相机,把黑板上的字照下来,给你看罢了。

另外,一个c++的傻逼错误,居然用指针共享对象,然后指针被后面的操作改变了,都没有发现,调试半天。








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值