2014-10-09 32 views
6

Fare tıklamaları kullanarak bir çizgi çiziyorum.Sınırlayıcı rect'in şeklini özelleştirme

QRectF Line::boundingRect() const 
{ 
    // bounding rectangle for line 
    return QRectF(start_p, end_p).normalized(); 
} 

enter image description here

Bu boyalı hattını göstermektedir:

painter->drawLine(start_p, end_p); 

hattının sınırlayıcı rect olarak tanımlanır: Satır boya fonksiyonu kullanılarak çekilir. gösterildiği gibi bunun için sınırlayıcı rect olsun:

enter image description here

Ben öğenin şekline göre sınırlayıcı rect sahip olmak istiyorum, bir şey gibi: enter image description here

Nasıl bunu başarmak için? Düzenleme

örtüşen hatlarının herhangi seçerken

, üstte rect sınırlayan bir kez (aşağıdaki şekle bakın) seçilir. setZValue kullanımından bile yararlanamayacaksınız. Bunu sınırlayıcı rect'i çizgi şeklini en aza indirerek uygulamak istiyorum.

enter image description here

+0

Bu bir çapraz gönderi. :) –

+1

['QGraphicsItem :: shape'] kullanın (http://qt-project.org/doc/qt-5/qgraphicsitem.html#shape). – thuga

+0

Ben bir yeniyim. Biraz demo kodu verebilir misiniz? –

cevap

-1

Sen bu gibi bazı şey istiyorsanız sınırlayıcı kendini çiz gerekir. Qt'nin QRect'i sınırlamak ve QRect'inizi önceki QRect, sol üst ve sağ alt köşelerine bağlı olarak tanımlamanıza izin verin. Örneğin, sol üst köşede (2,2) yeni QRect sol üstte (1,2) ve sağ üstte (2,1) ve

+0

"Böyle bir şey istiyorsanız, kendinizi sınırlayıcı çizmelisiniz" Bu hiç de doğru değil. – cmannett85

+0

benim noktayı azaltmak ve söylemek (basit değil) için basittir. Eğer soruya cevap verebilirsen. QGraphicsView tarafından bu özelliklerin tümüne sahip bir proje hazırlıyorum. Bu şeyi görmediyseniz, bunun doğru olmadığını söyleyemezsiniz. – QCoder

+0

Bu soruya cevap verebilirim, ama @thuga cevabı 45 dakika önce yorumladı ve rep onun iddiasıdır. Cevabınız yanlıştır, çünkü bunları ayarlamak için bir sınır çizmeniz gerekmez, 'QGraphicsItem :: boundingRect()' komutunu geçersiz kılabilirsiniz. Bundan başka, sınırlayıcı kutu eksenel olarak hizalanmıştır, böylece döndürülmüş bir dikdörtgenin çizimi gerçek sınırlayıcı kutunun çok daha büyük olmasına neden olacaktır. – cmannett85

1

İki ilgili işlev varsa İlgilendiğiniz bir QGraphicsItem içinde. Birincisi boundingRect. Bu, muhtemelen fark ettiğiniz gibi, tüm öğeyi kapsayan bir dikdörtgendir. Qt bunu, bir öğenin ne kadarının görünür olduğunu ve basit bir öğe çarpışması olduğunu hızlı bir şekilde hesaplamak için kullanır.

Dikdörtgen öğeleriniz varsa bu harikadır; QGraphicsItem veya QGraphicsObject öğesinden devraldığınız öğelerde boundingRect()'u geçersiz kılabilirsiniz.

Düzenli olmayan ve öğenin şekliyle çarpışma gibi şeyler yapmak istediğiniz bir şekle sahipseniz, shape() işlevinin sınıfınızda da geçersiz kılınması gerekir. Şimdi

QPainterPath Line::shape() 
{ 
    QRectF rect(start_p, end_p).normalized(); 

    // increase the rect beyond the width of the line 
    rect.adjust(-2, -2, 2, 2); 

    QPainterPath path; 
    path.addRect(rect); 

    return path; // return the item's defined shape 
} 

yerine boundingRect (içinde, şekil() öğesini çizmek için bir ressam kullanabilirsiniz) ve çarpışma çalışacak, -: Eğer böyle bir şey yapmak, böylece

Bu, bir QPainterPath döndürür beklenildiği gibi.

6

Dikdörtgen gibi olmayan bir öğeye sahipseniz veya döndürülen bir dikdörtgen varsa QGraphicsItem::shape kullanın.

Bu işlev bir QPainterPath döndürmelidir. Yolunuzu QPainterPath::addPolygon kullanarak oluşturabilmeniz gerekir.İşte

küçük örnektir:

QPainterPath Item::shape() const 
{ 
    QPainterPath path; 
    QPolygon polygon; 
    polygon << QPoint(0, 0); 
    polygon << QPoint(5, 5); 
    polygon << QPoint(width, height); 
    polygon << QPoint(width - 5, height - 5); 
    path.addPolygon(polygon); 

    return path; 
} 

elbette farklı bir şekilde yolunun içine noktaları hesaplamak gerekir, ancak noktası olsun. Şimdi bir öğeye tıkladığınızda, yalnızca tıklama, QPainterPath tarafından tanımlanan şekil içinde gerçekleşmişse onu seçecektir.

Kıvrımlı çizgiler yapmanıza gerek duyarsanız, cmannett85 tarafından önerilen şekilde QPainterPathStroker::createStroke kullanabilirsiniz. Sahnenin boyama işlemini en iyi hale getirmek için her zaman

1

boundingRect kullanılır. Yani burada manipülasyona yer yok. Fare etkileşimi için alan değiştirmek isterseniz, shape method.

BUT Varsayılan olarak, bu yöntem boundingRect yönteminden alınan QPainterPath dikdörtgeni döndürür.
Bu yöntemi geçersiz kılın ve istenen şekli sağlayın.

QPainterPath YourGraphicsItem::shape() const { 
    static const qreal kClickTolerance = 10; 

    QPointF vec = end_p-start_p; 
    vec = vec*(kClickTolerance/qSqrt(QPointF::dotProduct(vec, vec))); 
    QPointF orthogonal(vec.y(), -vec.x()); 

    QPainterPath result(start_p-vec+orthogonal); 
    result.lineTo(start_p-vec-orthogonal); 
    result.lineTo(end_p+vec-orthogonal); 
    result.lineTo(end_p+vec+orthogonal); 
    result.closeSubpath(); 

    return result; 
}