2016-09-29 67 views
2

我確實有2個QDeclarativeItems。Qt傳播背景項目上的繪畫事件

void BackgroundLayer::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 
{ 
    painter->drawImage(QRectF(dx1, dy1, dx2-dx1, dy2-dy1), shownImage, QRectF(sx1, sy1, sx2-sx1, sy2-sy1)); 
} 

void ForegroundLayer::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 
{ 
    QPen pen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); 
    painter->setPen(pen); 
    painter->drawLine(p1, p2); 
} 

QML

Rectangle { 
    width: 1920 
    height: 1080 

    BackgroundLayer{ 
     id: background_layer 
     anchors.fill: parent 
    } 

    ForegroundLayer { 
     id: foreground_layer 
     anchors.fill: parent 
    } 
} 

借鑑ForegroundLayer觸發BackgroundLayer油漆事件,導致其重繪整個圖像。因此,繪圖工作緩慢。是否有可能避免這種情況,只有在真正需要時才重新繪製圖像?

+0

WA_OpaquePaintEvent和WA_TranslucentBackground使其稍快(出於某些原因),但圖像仍被重新繪製。這不起作用。 –

+0

如果你把'BackgroundLayer'和'ForegroundLayer'放到'Rectangle {children:[]}裏面會發生什麼' – UmNyobe

+0

'Rectangle {children:[]}'沒有變化' –

回答

1

你爲什麼期待其他類型的行爲? Qt並沒有爲你保留每個聲明項目的圖像,在內存方面它會非常昂貴。不過,您可以選擇啓用此功能:也許您應該。請參閱cacheMode文檔。

當任何項目需要更新時,下面和與更新矩形相交的所有內容都必須重新進行重新繪製,按Z順序從下到上。如果QGraphicsView下面有任何小部件,並且視圖本身是半透明的,那麼這些小部件也必須重新繪製。

如果您確切知道需要更新的區域,您應該使用以下知識:呼叫QGraphicsItem::update(const QRectF &)來指示需要更新的區域。否則,使用空矩形,更新區域跨越整個項目。

還要確保QGraphicsViewupdateMode設置爲MinimalViewportUpdate

在封面下,所有QGraphicsItem實例和所有QWidget實例都在內部QImage上繪製,然後將其內置或交換到底層本機窗口。它們以前後Z順序繪製,唯一被跳過的小部件或項目是完全包含在不透明小部件或項目下的部件或項目。

+0

是的,這是真的,但是,沒有辦法至少限制繪圖區域,所以我不必重新繪製整個圖像?我知道setClipRect(),它不是一個解決方案。如果我f.ex.畫一條從左上角到右下角的對角線,整個畫面被重新繪製,儘管只有一小部分變化。 –

+0

請參閱編輯....... –

1

簡短的回答:只需使用轉換一次QPixmapshownImage

void BackgroundLayer::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 
{ 
    painter->drawPixmap(QRectF(dx1, dy1, dx2-dx1, dy2-dy1), shownPixmap, QRectF(sx1, sy1, sx2-sx1, sy2-sy1)); 
} 

說明

在屏幕上畫像素圖比圖片要快得多。其他選擇可能無效或太複雜。

繪畫事件從頂層小部件傳播到子節點。 基本上Qt被賦予一個矩形來繪製,並且這個矩形內的每個小部件都會收到一個繪製事件。

我相信你想實現可能與小部件某些特定情況下是可行的屬性黑客什麼,但我看不出你怎麼能在這裏做沒有從ForegroundLayer有舊漆的文物。

假設你有兩行ABCD

  • 第一個電話後作畫,你只想看到線AB
  • 的P1後,P2已經更新,你只希望看到線CD

爲了防止你看到AB行繪製的時候CD,Qt 已經到清除矩形被繪的整個背景。如果由於某種原因BackgroundLayer不繪製,背景圖像將消失。