QGraphicsView 框架学习(六) 设计问题
2015-07-06 17:46
274 查看
书到用时方恨少啊,遇到一个设计问题,为了给QGraphicsItem添加一些特性,比如给它们添加一个选择框,提供resize操作,前面用的方法是子类化这个类,现在发现这个方法挺麻烦的。赶快翻书,《设计模式》给出了Adapter等结构模式,《设计模式新思维》给出了模板实现设计模式的方法,目前的问题是尽量利用Qt提供的现成的类,尽量复用现有的工具,那么就 Adapter+template吧。可是问题又来啦,我们需要动多态啊,item需要动态绑定啊,没找到template动态绑定的方法,只能自己做实验了。
定义一个模板基类,模板参数传递一个QGraphicsItem类型。我们可以实现不同的子类来完成QGraphicsItem的resize操作,而不用对QGraphicsItem类型做修改。这个类,提供了两个方法,resize用来改变图形大小。另外一个给图形添加文本。
//声明了一个基本类型做我接口类,模板参数选择的是 QGraphicsItem,和AbstractControl类,它们同样都是基本的接口类型。
//动态绑定
//相当于
// class RCShape : public EllipseControl , public QGraphicsEllipseItem;
//动态绑定
//相当于
//class RCShape : public RectControl , public QGraphicsRectItem;
//动态绑定
//相当于
//class RCShape : public NullControl , public QGraphicsSimpleTextItem;
总结,mixin模式模板类作为接口类,实现动多态也是可以的,但是需要对多重继承的父类定义抽象接口,声明一个完全都是基本类型的模板类做接口对象的类型。然后通过dynamic_cast实现动态绑定。
定义一个模板基类,模板参数传递一个QGraphicsItem类型。我们可以实现不同的子类来完成QGraphicsItem的resize操作,而不用对QGraphicsItem类型做修改。这个类,提供了两个方法,resize用来改变图形大小。另外一个给图形添加文本。
template < typename T > class AbstractControl { public: AbstractControl( T * shape ) :m_shape(shape) {} virtual void reszie( int handle , const QPointF & point ){ qDebug()<<"AbstractControl:"<< m_shape->boundingRect(); } virtual void setText( const QString& text ) {} protected: ~AbstractControl(){} T * m_shape; }; // 适配QGraphicsSimpleTextItem对象 template < typename T > class NullControl : public AbstractControl<T> { public: NullControl( T * shape ) :AbstractControl<T>(shape) {} void reszie( int handle , const QPointF & point ){ qDebug()<<"NullControl:"<< AbstractControl<T>::m_shape->boundingRect(); } void setText(const QString& text ) { AbstractControl<T>::m_shape->setText(text); } }; //矩形对象 template < typename T > class RectControl : public AbstractControl<T> { public: RectControl( T * shape ) :AbstractControl<T>(shape) {} void reszie( int handle , const QPointF & point ){ AbstractControl<T>::m_shape->setRect(-50,-50,100,100); qDebug()<<"RectControl:"<< AbstractControl<T>::m_shape->boundingRect(); } }; //椭圆对象 template < typename T > class EllipseControl : public AbstractControl<T> { public: EllipseControl( T * shape ) :AbstractControl<T>(shape) {} void reszie( int handle , const QPointF & point ){ AbstractControl<T>::m_shape->setRect(-50,-50,100,100); AbstractControl<T>::m_shape->setStartAngle(30*16); AbstractControl<T>::m_shape->setSpanAngle(120*16); qDebug()<<"EllipseControl:"<< AbstractControl<T>::m_shape->boundingRect(); } }; //定义一个图元,多重继承 AbstractControl和QGraphicsItem类,我们可以在这里继续给它添加一些通用功能。 template < class BaseType , template<class> class Control > class RCShape : public Control < BaseType > ,public BaseType { public: RCShape(QGraphicsItem * parent = 0 ) : Control< BaseType >( this ),BaseType(parent) { BaseType::setFlag(QGraphicsItem::ItemIsMovable, true); BaseType::setFlag(QGraphicsItem::ItemIsSelectable, true); BaseType::setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); this->setAcceptHoverEvents(true); } }; //template的动态多态,不知道真正的template是怎么实现动多态的,反正我就是这么实现的。
//声明了一个基本类型做我接口类,模板参数选择的是 QGraphicsItem,和AbstractControl类,它们同样都是基本的接口类型。
typedef RCShape<QGraphicsItem,AbstractControl> AbstractShape;
//动态绑定
//相当于
// class RCShape : public EllipseControl , public QGraphicsEllipseItem;
AbstractShape *item = qgraphicsitem_cast<AbstractShape*> (new RCShape<QGraphicsEllipseItem , EllipseControl >); item->reszie(0,QPointF()); item->setPos(scene->sceneRect().center()); scene->addItem(item);
//动态绑定
//相当于
//class RCShape : public RectControl , public QGraphicsRectItem;
AbstractShape *item1 = qgraphicsitem_cast<AbstractShape*> (new RCShape<QGraphicsRectItem , RectControl > ); item1->reszie(0,QPointF()); item1->setPos(300,300); scene->addItem(item1);
//动态绑定
//相当于
//class RCShape : public NullControl , public QGraphicsSimpleTextItem;
AbstractShape *item2 = qgraphicsitem_cast<AbstractShape*> (new RCShape<QGraphicsSimpleTextItem , NullControl > ); item2->reszie(0,QPointF()); item2->setText(tr("Demo C++ Template Dynamic Polymorphism")); item2->setPos(300,200); scene->addItem(item2);
总结,mixin模式模板类作为接口类,实现动多态也是可以的,但是需要对多重继承的父类定义抽象接口,声明一个完全都是基本类型的模板类做接口对象的类型。然后通过dynamic_cast实现动态绑定。
相关文章推荐
- xcode6手动添加pch文件
- swift 之 URL编码
- android中Textview和图片同时显示时
- 不使用递归和栈实现二叉树的中序遍历
- 瓦片地图,通过像素坐标返回瓦片坐标的函数
- Spring.Net集成NHibernate配置
- Xcode6为什么干掉pch(Precompile Prefix Header)&如何添加pch文件
- 博客已死?移动互联网时代博客的价值
- Android Studio 初体验
- 统计 YARN 提交任务的Hostname 分布
- Selenium_WebDriver下拉框练习_Java
- Unreal Engine 4 一些小技巧或提示
- 多目标进化问题,根据PCI进行小区的聚类,Kmeans算法的改进:二次聚类
- 六、数组及输入方式
- 安装Redis完整过程
- Mongodb for Mac 安装
- Django模块笔记【五】
- 判断内核
- Oracle之 数据分页查询
- mysql学9-优化