QGraphicsView和装饰模式

时间:2014-03-13 13:01:32

标签: c++ qt oop design-patterns

该问题适用于qt库的类QGraphicsView。 但是,问题更为笼统。所以,如果我没有错过qt中的任何特殊机制,可以在不知道qt的情况下进行讨论。

我正在继承QGraphicsView以添加我需要的一些功能。 例如。我有ScalableViewPannableViewLabeledView来添加独立功能。

我现在使用的子类在以下意义上是线性的: ScalableView源自QGraphics视图。 PannableView源自ScalableView视图。 LabeledView源自PannableView视图。

由于这些功能是独立的,因此存在设计缺陷。 应用装饰器模式来解决这个问题对我来说似乎很合适。 问题是,QGraphicsView不是接口,并且不存在像 QAbstractGraphicsView 这样的接口类。所以,对我而言,尚不清楚该模式是如何实现的。

另一个想法是使用模板。因此,我可以从模板T派生每个视图。然后,我可以制作ScalableView<PannableView<LabeledView>>>

等信息

你认为有更好的解决方案吗?在这种情况下,我更喜欢一种实现装饰器模式的方法,因为我想避免使用会增加编译时间的许多模板类。

2 个答案:

答案 0 :(得分:3)

Qt风格的一个简单解决方案是创建一个派生自QGraphicsView的类,并且只具有控制其行为的标志(无论是可扩展的,可扩展的,标记的等)。这些行为的实现仍然会被分解为方法,所以它就是 不像看起来那样单片。

装饰器模式当然可以通过定义中间(垫片)接口来轻松实现。 QGraphicsView不需要实现该接口 - 该接口仅供装饰器使用。

深度继承的问题在于,无法精确控制行为的相互作用。您拥有的唯一控件是事件处理的顺序。这可能恰好足够了,但我有点担心。没有点缀的装饰模式分享了这个问题。

答案 1 :(得分:1)

在不知道完整设计的情况下,这可能会或可能不会起作用,但也许这会有所帮助。

一种可能的方法是封装QGraphicsView并创建提供所需的不同功能的委托对象。然后,代表将负责提供图形视图和转发消息的接口。

这意味着为不同类型的功能创建不同的委托;一个ScalableDelegate,一个PannableDelegate和一个LabeledDelegate。

由于委托是单独的对象而不是从QGraphicsView继承,因此您可以通过在图形视图上安装事件过滤器来获得许多功能。

然后,它们不是与GraphicsView交互的对象,而是通过相关的委托进行通信。

如果限制太多,您可能需要从QGraphicsView继承以创建具有所需功能的视图,然后使用委托根据需要公开所需的功能。