2009-07-13 11 views
14

QT 4.5로 페인팅 프로그램을 수행하려고하므로 QGraphicsView를 캔버스에 사용하고 QGraphicsScene에서 항목을 저장합니다. 내가는 QWidget의 자식이기 위하여는 DrawingCanvas을 변경하는 경우 몇 가지 이유를 들어, 난 그냥,QT 4.5 - QGraphicsView에서 QPainter 장치를 얻는 방법

class DrawingCanvas : public QGraphicsView 
{ 
    DrawingCanvas::DrawingCanvas(QWidget * parent); 

... 
}; 

DrawingCanvas::DrawingCanvas(QWidget * parent = 0) : QGraphicsView(parent) 
{ 
    .... 
} 

void DrawingCanvas::paintEvent(QPaintEvent& paintEventInfo) 
{ 
    // Result in painter not active 
    QPainter(this); 
    ... 
} 

그러나 내 자신의 유래를 QGraphicsView에 QPainter를 컨텍스트를 가져올 수 없습니다, 그것은 작동합니다. QGraphicsView가 QAbstractScrollArea, QFrame, QWidget에서 파생 된 것을 보면 코드가 작동 할 것으로 기대합니다.

그래서 나는 질문이 추측 :

1) 왜이 활성화 QPainter를을 얻기 위해를 QGraphicsView에 paintEvent를 사용할 수 있다는 것입니다? 2) 가능할 수도 있나요?

미리 감사드립니다.

답변

15

누군가가 여전히 가능하면 궁금해하는 사람이 있다면 대답은 '예'입니다.

짧은 버전

void DrawingCanvas::paintEvent(QPaintEvent& paintEventInfo) 
{ 
    // Result in painter active 
    QPainter(viewport()); 
    ... 
} 

롱 버전

QGraphicsScene 자체에 어떤 그림을하지 않습니다 대신 당신이 그것을 또는 기본는 QWidget으로 제공 뷰포트 위젯을 그린다.

대신 뷰포트에 그림을 그리면 장면이 아닌보기에 정렬되는 오버레이 된 그림을 얻을 수 있습니다. 또는 QGlWidget 및 해당 paintOverlayGl()을 사용할 수 있습니다.

또한 viewportUpdateMode (QGraphicsView :: FullViewportUpdate)를 설정해야합니다. 그렇지 않으면 렌더링 아티팩트가 생성됩니다. 매번 전체보기를 업데이트하는 것보다 유물을 피하는 더 현명한 방법이있을 수 있지만 성능 문제가 발생할 때까지 기다려야합니다.

4

오른쪽, 잠시 동안 머리카락을 꺼내서, 이것은 불가능한 것처럼 보이므로 여기 내 해결책이 있습니다. 그리는 모든 것을 QGraphicsScene에 추가해야합니다. 그래서 당신은 그것으로부터 당신 자신의 구현을 파생시킨다.

가장 간단한 방법은 그리려는 선, 사각형 및 기타에 대한 임시 QGraphicsItem 포인터를 정의하는 것입니다.

가상 mousePressed(), mouseMove() 및 mouseRelease() 이벤트를 적절하게 재정의하십시오. mousePressed()에서 temp QGraphicsItem 포인터를 초기화하고 장면에 추가합니다.

mouseMoved() 내에서 temp QGraphicsItem의 좌표를 적절히 설정하십시오. mouseReleased의 경우, temp 오브젝트의 사본을 작성하여 장면에 추가하고 화면에서 선, 직사각형 등을 그리기 위해 사용했던 temp QGraphicsItem을 제거하십시오.

QGraphicsView 내에 QPainter 컨텍스트가없고 그 paintEvent()를 무시하는 것이 더 낫다는 것이 도덕적이라고 생각합니다.

희망 사항은이 문제에 직면 할 수있는 사람에게 도움이되기를 바랍니다.

+1

방금 ​​전과 똑같은 과정을 거쳤습니다. <임시 품목을 훨씬 쉽게 그리게 만들 거라고 생각합니다. 다른 해결 방법이 있지만 ... 오버 페인트입니다. 보이지 않는 위젯을 덮어 씌울 수 있고, 실제로 원한다면 페인트 할 수 있습니다. – mpen

1

다른 가능성 :보기에서 drawForeground을 재정의하십시오. 그리는 데 필요한 항목의 종류에 따라 매우 간단한 해결책 (예 : 마커 선의 오버레이)이거나 때로는 장면에 맞춤 항목을 만드는 것보다 효과적 일 수 있습니다. 원하는 결과에 따라 달라질 수 있습니다.

관련 문제