2013-08-24 5 views
1

이미지를로드하는 QGraphicsView 하위 클래스가 있습니다. 그런 다음 사용자는 클릭하고 드래그하여 해당 이미지에 선을 그릴 수 있습니다.QgraphicsScene에서 선을 하나씩 취소하거나 삭제합니다.

void TabView::mousePressEvent(QMouseEvent *event){ 
    if (event->button() == Qt::LeftButton) { 
     lineList<<line; 
     scene->addLine(lineList.last()); 
    } 
} 

void TabView::keyPressEvent(QKeyEvent * event){ 
    int key = event->key(); 
    switch(key){ 
     case Qt::Key_Delete: 
     { 
      lineList.removeLast(); 
      foreach(QLineF line, lineList){ 
       scene->addLine(line); 
      } 
      scene->update(); 
      break; 
     }    
    } 
} 

그러나이 작동하지 않습니다

void TabView::mousePressEvent(QMouseEvent *event){ 
    if (event->button() == Qt::LeftButton) { 
     scene->addLine(line); 
    } 
} 

는이 같은 실행 취소 기능을 추가했다. 나는 이것을 시도했다

case Qt::Key_Delete: 
    QGraphicsLineItem *item = new QGraphicsLineItem(lineList.last()); 
    scene->removeItem(item); 
    scene->update(); 
    break; 

그러나 이것도 작동하지 않는다.

내 문제는 : QgraphicsScene에서 항목을 하나씩 실행 취소하거나 삭제할 수있는 방법은 무엇입니까?

편집 : 이것 보기는 :

case Qt::Key_Delete: 
{ 
    itemList = scene->items(); 
    itemList.removeLast(); 
    foreach(QGraphicsItem *item, itemList){ 
     scene->addItem(item);     
    } 
    scene->update(); 
    break; 
} 

그것은 작동 할 것으로 예상하지만,하지 않습니다.

정말 왜 작동하지 않는지 궁금합니다. 당신의 삭제 코드에서

답변

3

:

case Qt::Key_Delete: 
    QGraphicsLineItem *item = new QGraphicsLineItem(lineList.last()); 
    scene->removeItem(item); 
    scene->update(); 
    break; 

당신은 새로운 QGraphicsLineItem 개체를 만들 수 있습니다. 이 개체는 장면에 존재하지 않으므로 scene->removeItem(item)을 실행하면 아무 작업도 수행되지 않습니다.

개체를 만들 때 사용하는 QLineF 개체가 아닌 씬에 추가하는 모든 QGraphicsLineItem 개체를 추적해야합니다.

Qt Undo Framework에 대해 생각해 보셨습니까?

+0

예 알고 있습니다. 하지만 나는 아주 간단한 것을 원해. 내가 왜 작동하지 않는 골동품인가? – dare

+3

잘못된 항목을 추적하고 있습니다. 내 대답을 확장했습니다. 실행 취소 프레임 워크를 사용하면 생각보다 훨씬 간단한 대답이 될 수 있습니다. 또한'TabView' 클래스가 [god 객체] (http://en.wikipedia.org/wiki/God_object)가되지 않도록합니다. – RobbieE

2

이미 제안했듯이 Qt Undo Framework가 가장 적합합니다.

그러나 자신의 UNDO/REDO 기능을 구현하려면 실행 취소 및 다시 실행을위한 작업 스택 목록을 유지 관리해야합니다.

예를 들어 listUndo라는 스택과 listRedo라는 스택을 가질 수 있습니다.

  • 사용자가 행을 추가 할 때마다 또는 목록에서 다른 작업을 수행 할 때마다 목록 실행 취소 작업을 수행하십시오. 또한 사용자가 모든 작업을 수행 할 때마다 listRedo 스택을 지우는 것을 잊지 마십시오.

  • 사용자가 "UNDO"를 누르면 listUndo 스택에서 수행 된 마지막 작업이 튀어 나오고, 해당 작업을 취소하고 해당 작업을 listRedo 스택으로 푸시합니다.

  • 사용자가 "REDO"를 누르면 listRedo 스택에서 마지막으로 수행 한 작업을 취소하고 해당 작업을 다시 실행 한 다음 해당 작업을 listUndo 스택으로 푸시합니다. 내가 말했듯이

는 당연히, 위에서 그래서 가장 잘은 Qt를 취소 프레임 워크의 기능 내장 사용하는 것, 조금 까다로운 및 버그가 발생하기 쉬운 것 같다.