2014-10-09 19 views
6

Tôi đang vẽ một đường bằng cách sử dụng nhấp chuột. Các đường thẳng được vẽ sử dụng chức năng sơn như:Tùy chỉnh hình dạng của biên giới rect

painter->drawLine(start_p, end_p); 

các rect giới hạn của dòng được định nghĩa là:

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

enter image description here

Điều này cho thấy dòng sơn. Tôi nhận được rect bounding cho điều này như:

enter image description here

Tôi muốn có rect bounding theo hình dạng của mặt hàng đó, một cái gì đó như: enter image description here

Làm thế nào để đạt được điều này?

Sửa

Trong khi lựa chọn bất kỳ của các dòng chồng chéo, một với bounding rect trên đỉnh được chọn (xem hình bên dưới). Ngay cả khi sử dụng setZValue sẽ không hoạt động ở đây. Tôi muốn thực hiện điều này bằng cách giảm thiểu ranh giới liên kết với hình dạng của đường kẻ.

enter image description here

+0

Đây là một bài đăng chéo. :) –

+1

Sử dụng ['QGraphicsItem :: shape'] (http://qt-project.org/doc/qt-5/qgraphicsitem.html#shape). – thuga

+0

Tôi là người mới. Bạn có thể vui lòng cung cấp một số mã demo không. –

Trả lời

-1

Bạn phải vẽ mình bounding nếu bạn muốn có một số điều như thế này. hãy để Qt có QRect cho ràng buộc và xác định QRect mới của bạn phụ thuộc vào góc của QRect trước đó, trên cùng bên trái và dưới cùng bên phải. ví dụ: nếu góc trên cùng bên trái là (2,2) phía trên cùng bên trái của bạn là (1,2) và trên cùng bên phải là (2,1) và ...

+0

"Bạn phải tự vẽ mình nếu bạn muốn một số thứ như thế này" Điều này không đúng chút nào. – cmannett85

+0

nó đơn giản để giảm điểm của tôi và nói (nó không phải là sự thật ở tất cả). nếu bạn có thể trả lời câu hỏi. Tôi tạo toàn bộ dự án bằng QGraphicsView với tất cả các tính năng này. Nếu bạn không thấy điều này bạn không thể nói nó không đúng. – QCoder

+0

Tôi có thể trả lời câu hỏi, nhưng @thuga đã cung cấp câu trả lời trong một bình luận 45 phút trước và đại diện là của anh/cô ấy để yêu cầu bồi thường. Câu trả lời của bạn là sai bởi vì bạn không cần phải vẽ một giới hạn theo thứ tự trong thiết lập chúng, bạn có thể ghi đè 'QGraphicsItem :: boundingRect()'. Hơn nữa hộp giới hạn là trục liên kết để vẽ một hình chữ nhật xoay sẽ gây ra hộp giới hạn thực tế là lớn hơn nhiều. – cmannett85

1

Có hai chức năng liên quan trong QGraphicsItem mà bạn nên quan tâm. Đầu tiên là boundingRect. Điều này, như bạn có thể nhận ra là một hình chữ nhật bao gồm toàn bộ mục. Qt sử dụng điều này cho những thứ như vậy một cách nhanh chóng tính toán bao nhiêu của một mục có thể nhìn thấy và va chạm mục đơn giản.

Thật tuyệt vời nếu bạn có các mục hình chữ nhật; bạn chỉ có thể ghi đè boundingRect() trong bất kỳ mục nào bạn thừa kế từ QGraphicsItem hoặc QGraphicsObject.

Nếu bạn có hình dạng không thường xuyên và bạn muốn làm những việc như va chạm với hình dạng của mặt hàng, thì chức năng shape() cũng cần ghi đè trong lớp học của bạn.

này trả về một QPainterPath, vì vậy bạn có thể làm một cái gì đó như thế này: -

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 
} 

Bây giờ, bạn có thể sử dụng một họa sĩ để vẽ hình dạng() mục, thay vì các boundingRect() và va chạm sẽ làm việc như mong đợi.

6

Nếu bạn có một mục không được định hình như hình chữ nhật hoặc là hình chữ nhật được xoay sử dụng QGraphicsItem::shape.

Chức năng này phải trả lại QPainterPath. Bạn sẽ có thể tạo đường dẫn của mình bằng cách sử dụng QPainterPath::addPolygon.

Dưới đây là một ví dụ nhỏ:

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; 
} 

Bạn dĩ nhiên nên tính toán điểm của bạn trong con đường theo một cách khác nhau, nhưng bạn sẽ có được điểm. Bây giờ khi bạn nhấp vào một mục, nó sẽ chỉ chọn mục đó nếu nhấp chuột xảy ra bên trong hình được xác định bởi QPainterPath.

Nếu bạn cần tạo đường cong, bạn có thể sử dụng QPainterPathStroker::createStroke như được gợi ý bởi cmannett85.

1

boundingRect luôn được sử dụng để tối ưu hóa quá trình vẽ của cảnh. Vì vậy, bạn không có chỗ cho thao tác ở đây.

NHƯNG nếu bạn muốn thay đổi diện tích tương tác chuột có shape method. Theo mặc định, phương thức này trả về QPainterPath hình chữ nhật nhận được từ phương thức boundingRect.
Vì vậy, chỉ cần ghi đè phương pháp này và cung cấp hình dạng mong muố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; 
} 
Các vấn đề liên quan