2009-08-03 33 views
7

Tôi đang sử dụng các lớp con QGraphicsView- và QGraphicsItem của Qt. là có cách để không mở rộng biểu diễn đồ họa của mục trong chế độ xem khi hình chữ nhật chế độ xem được thay đổi, ví dụ: khi phóng to. Hành vi mặc định là quy mô các mục của tôi có liên quan đến hình chữ nhật chế độ xem của tôi.QGraphicsView và QGraphicsItem: không quy mô mục khi mở rộng chế độ xem trực tiếp

Tôi muốn hình dung các điểm 2d nên được thể hiện bằng hình chữ nhật mỏng không được chia tỷ lệ khi phóng to trong chế độ xem. Xem phần mềm mô hình hóa 3D điển hình để tham khảo nơi các điểm đỉnh luôn được hiển thị ở cùng kích thước.

Cảm ơn!

+1

Ngoài ra hãy đỉnh tại http://doc.trolltech.com/4.5/qpen.html#setCosmetic nếu bạn đang sử dụng một lớp sơn tùy chỉnh thói quen – mpen

Trả lời

9

Đặt cờ của mục QGraphicsItem :: ItemIgnoresTransformations thành true không hoạt động cho bạn?

+4

này thực sự đảm bảo kích thước của mặt hàng đó là đúng, nhưng ít nhất là trong trường hợp của tôi, các vị trí bị tắt sau khi biến đổi. Ví dụ: khi tôi vẽ đa giác trong ứng dụng của mình và thêm các mục hình chữ nhật con vào chế độ xem chưa được đánh dấu (1: 1), tôi nhận được kết quả sau: http://grafit.mchtr.pw.edu.pl/~szczedar/ nozoom.png. Sau khi chia tỷ lệ và với bộ cờ, có vẻ như sau: http://grafit.mchtr.pw.edu.pl/~szczedar/zoomout.png – neuviemeporte

+1

Các tài liệu nói rằng mục có bộ cờ vẫn được neo vào phụ huynh, nhưng Tôi đã tạo đối tượng rect với đa giác làm cha mẹ và nó không hoạt động.Đã thử mục pixmap bên dưới làm cha mẹ, không thay đổi. – neuviemeporte

2

Làm thế nào về điều này:

#include <QtGui/QApplication> 
#include <QtGui/QGraphicsScene> 
#include <QtGui/QGraphicsView> 
#include <QtGui/QGraphicsRectItem> 

int main(int argc, char* argv[]) { 
    QApplication app(argc, argv); 
    QGraphicsScene scene; 
    scene.addText("Hello, world!"); 
    QRect rect(50, 50, 100, 100); 
    QGraphicsRectItem* recti = scene.addRect(rect); 
    QGraphicsView view(&scene); 

    // Set scale for the view 
    view.scale(10.0, 5.0); 

    // Set the inverse transformation for the item 
    recti->setTransform(view.transform().inverted()); 

    view.show(); 
    return app.exec(); 
} 

Như bạn có thể thấy văn bản được nhân rộng nhưng hình chữ nhật thì không. Lưu ý rằng điều này không chỉ ngăn cản việc mở rộng hình chữ nhật mà còn là phép biến đổi khác.

1

Tôi thấy rằng nếu tôi lấy được một lớp mới và reimpliment chức năng sơn tôi có thể làm

void MyDerivedQGraphicsItem::paint(QPainter *painter, 
            const QStyleOptionGraphicsItem *option, 
            QWidget *widget) 
{ 
    double scaleValue = scale(); 
    double scaleX = painter->transform().m11(); 
    setScale(scaleValue/scaleX); 
    QGraphicsSvgItem::paint(painter,option,widget); 
} 

Đây là cách tốt nhất để làm việc đó mà tôi đã tìm thấy cho đến nay, nhưng tôi vẫn đang mày mò xung quanh.

+1

Hm. Điều này đã không làm việc cho tôi (trong trường hợp của tôi tôi đang phân lớp QGraphicsEllipseItem). Mục vẫn lớn hơn khi tôi phóng to chế độ xem. Bạn có làm gì ngoài việc ở trên không? – estan

+0

Bah xin lỗi, nó thực sự đã làm việc. Nhưng tôi muốn được quan tâm nếu bạn tìm thấy bất kỳ cách nào khác? Bởi vì khi tôi phóng to chế độ xem nhanh (sử dụng bánh xe cuộn) Tôi có thể nhận thấy một số nhấp nháy:/ – estan

+0

Xin lỗi, không, tôi vẫn gặp một số vấn đề với nó nhưng nó đã bị bỏ rơi. – enriched

3

Tôi gặp vấn đề tương tự, và phải mất một lúc để tìm ra. Đây là cách tôi giải quyết nó.

Mở rộng lớp QGraphicsItem, ghi đè lên sơn(). Bên trong lớp sơn(), đặt lại hệ số co giãn của biến đổi thành 1 (là m11 và m22), và lưu hệ số tỷ lệ m11 (x) và m22 (hệ số tỷ lệ y) trước khi đặt lại. Sau đó, vẽ như bạn thường làm nhưng nhân x của bạn với m11 và y với m22. Điều này tránh được việc vẽ với phép biến đổi mặc định, nhưng tính toán rõ ràng các vị trí theo chuyển đổi của cảnh.

void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) 
{ 
    QTransform t = painter->transform(); 
    qreal m11 = t.m11(), m22 = t.m22(); 
    painter->save(); // save painter state 
    painter->setTransform(QTransform(m11, t.m12(), t.m13(), 
            t.m21(), 1, t.m23(), t.m31(), 
            t.m32(), t.m33())); 
    int x = 0, y = 0; // item's coordinates 
    painter->drawText(x*m11, y*m22, "Text"); // the text itself will not be scaled, but when the scene is transformed, this text will still anchor correctly 
    painter->restore(); // restore painter state 
} 

Khối mã sau đây được vẽ với chuyển đổi mặc định

void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) 
{ 
    int x = 0, y = 0; 
    painter->drawText(x, y, "Text"); 
} 

Bạn có thể thử cả hai để thấy sự khác biệt. Hi vọng điêu nay co ich.

1

Các giải pháp sau đây làm việc một cách hoàn hảo đối với tôi:

void MyDerivedQGraphicsItem::paint(QPainter *painter, const StyleOptionGraphicsItem *option, QWidget *widget) 
{ 
    double scaleValue = scale()/painter->transform().m11(); 
    painter->save(); 
    painter->scale(scaleValue, scaleValue); 
    painter->drawText(...); 
    painter->restore(); 
    ... 
} 

Chúng tôi cũng có thể nhân scaleValue bởi mesures khác mà chúng tôi muốn giữ kích thước của nó không thay đổi bên ngoài môi trường lưu/khôi phục.

QPointF ref(500, 500); 
    QPointF vector = scaleValue * QPointF(100, 100); 
    painter->drawLine(ref+vector, ref-vector); 
Các vấn đề liên quan