2014-03-13 124 views
0

該問題適用於qt庫的類QGraphicsView。 但是,問題更一般。所以,如果我在qt中沒有遺漏任何特殊的機制,那麼可能會在不知道qt的情況下討論它。QGraphicsView和裝飾器模式

我將子類QGraphicsView添加一些我需要的功能。 例如我有一個ScalableView,PannableViewLabeledView添加獨立的功能。

我現在使用的子類在以下意義上是線性的: ScalableView是從QGraphics視圖派生而來的。 PannableView源自ScalableView查看。 LabeledView源自PannableView的觀點。

由於這些功能是獨立的,因此存在設計缺陷。 應用修飾器模式來看看這對我來說似乎很合適。 存在的問題是,QGraphicsView不是接口,並且不存在接口類,如QAbstractGraphicsView。所以,對我而言,這種模式如何實施尚不清楚。

不同的想法是使用模板。所以我可以從模板T推導出每個視圖。然後,我可以進行檢測,如ScalableView<PannableView<LabeledView>>>

您是否看到更好的解決方案?我更喜歡在這種情況下實現裝飾器模式的方式,因爲我想避免使用許多模板類來增加編譯時間。

+0

什麼是一個ScalableView和PannableView添加到的QGraphicsView,其中由類本身是不是已經可用?如果你只是刪除功能,那麼這是什麼原因? – TheDarkKnight

+0

這不是刪除,它是添加功能。它使得視圖可以使用鼠標滾輪進行縮放,並提供了適合視圖的功能。 PannableView使用鼠標提供左擊平移。 – SebastianK

+0

爲什麼不從QGraphicsView繼承一次,你是否需要不同的視圖與不同的功能? – TheDarkKnight

回答

3

Qt風格的簡單解決方案是創建一個派生自QGraphicsView的類,並且只是具有控制其行爲(無論是可縮放,可平移,標記等)的標誌。這些行爲的實現仍然會被分解爲方法,因此它不像看起來那樣是單一的。

裝飾模式當然可以通過定義一箇中間(墊片)接口來實現。 QGraphicsView不需要實現該接口 - 該接口僅供裝飾器使用。

深層繼承的問題是不可能精確控制行爲的交互。您擁有的唯一控件是事件處理的順序。這可能是足夠的,但它讓我有些擔心。沒有點綴的修飾器模式共享這個問題。

+0

謝謝,這將是一種方式。但正如你所提到的那樣,缺點是這種方法的單一性。在我看來,我想添加的功能對於單一方法來說太複雜了。 – SebastianK

+0

@SebastianK我沒有說它將它分解成單一的方法,只是將它分解成一般的方法。然後你會注意到它們如何通過一個公共的Shim接口暴露出來,並直接導向裝飾器模式。 –

1

不知道完整的設計,這可能會或可能不會工作,但也許這會有所幫助。

一種可能的方法是封裝QGraphicsView並創建提供您所需的不同功能的委託對象。代表然後將負責爲圖形視圖和轉發消息提供接口。

這將意味着爲不同類型的功能創建不同的委託;一個ScalableDelegate,一個PannableDelegate和一個LabeledDelegate。

由於代表是獨立的對象,不能從QGraphicsView繼承,因此您可以通過在圖形視圖上安裝事件過濾器獲得很多功能。

然後,而不是用你的GraphicsView相互作用的對象,他們通過與代表溝通。

如果這是過於嚴格,可能會需要從繼承的QGraphicsView來創建你所需要的功能的視圖,然後用代表爲需要暴露所需的功能。