2013-01-05 3 views
2

내 Qt 위젯의 다시 그리기/업데이트가 어려움 (QGraphicsView 클래스를 확장). 원하는 것은 사용자가 마우스를 누르고 움직일 때 대상 선택 영역을 강조 표시하는 직사각형 선택 상자입니다.Qt 페인팅 선택의 어려움

기본 워크 플로우 :

  1. MousePressEvent가 making_selection_box 플래그를 설정하고 시작 지점 (작업)을 저장합니다.
  2. MouseMoveEvent는 디스플레이를 업데이트해야하는지 확인합니다. 그럴 경우 시도합니다 (작동하지 않음).
  3. MouseReleaseEvent 핸들은 결과 선택 상자를 가져 와서 적절히 처리합니다. making_selection_box이 재설정됩니다. 선택 상자 아티팩트 (작동하지 않음)를 제거하려면 화면을 업데이트해야합니다.

오버라이드 mouseMoveEvent :

void QSchematic::mouseMoveEvent(QMouseEvent *event) 
{ 
    if(making_selection_box) 
    { 
     // get selection box 
     qDebug() << "updating selection box"; 
     curr_selection_end = event->pos(); 
     repaint(box(drag_select_start, curr_selection_end)); 
    } 
    // propogate event 
    QGraphicsView::mouseMoveEvent(event); 
} 

내 오버라이드 paintEvent :

void QSchematic::paintEvent(QPaintEvent *event) 
{ 
    qDebug() << "paintEvent"; 
    if(making_selection_box) 
    { 
     qDebug() << "drawing selection box"; 
     QPainter painter(viewport()); 
     painter.setPen(Qt::black); 
     painter.drawRect(box(drag_select_start, curr_selection_end)); 
     painter.end(); 
    } 
    // propogate event 
    QGraphicsView::paintEvent(event); 
} 

상자 내가 다른 선택 상자 시작/끝 지점에 대한 올바른 QRect를 만드는 데 썼다 단지 작은 도우미 함수입니다 .

static QRect box(const QPoint& p1, const QPoint &p2) 
{ 
    int min_x = p1.x(); 
    int min_y = p1.y(); 
    int max_x = p2.x(); 
    int max_y = p2.y(); 
    if(max_x < min_x) 
    { 
     max_x = min_x; 
     min_x = p2.x(); 
    } 
    if(max_y < min_x) 
    { 
     max_y = min_y; 
     min_y = p2.y(); 
    } 
    return QRect(min_x, min_y, max_x - min_x, max_y - min_y); 
} 

사용자가 버튼을 누르고 마우스를 움직일 때 mouseMoveEvent가 올바르게 트리거되는지 확인했습니다.

나는 또한 그런 최대화/최소화, 창 크기를 조정 등의 다양한 표준 작업을 수행 할 때 paintEvent는 등

나는 방법 난 것을 확인했습니다, 시스템에 의해 호출되는 것을 확인했습니다 내 위젯에 페인팅을 사용하면 다른 paintEvent 트리거와 올바르게 작동하므로 필자는 코드에서 다시 그리기를 트리거 할 수 없습니다.

repaint() 대신 update() 메서드를 사용하여 업데이트를 시도했지만 행운은 없습니다.

사이드 노트에서이 선택 상자 기능을 잘못된/어려운 방법으로 만들려고합니까? 마우스 리스너와 페인팅 코드를 수동으로 구현하지 않고도 선택 상자를 얻을 수있는 더 좋은 방법이 있습니까?

Visual Studio 2010 MSVC 컴파일러를 사용하여 Windows 7 x64에서 Qt 4.8.4로 테스트하고 있습니다.

답변

1

QGraphicsScene API를 살펴본 후 수동으로 선택 상자를 관리해야하는 쉬운 방법을 발견했습니다. 끌기 모드를 RubberBandDrag으로 설정해야합니다.

편집 :

더 다른 목적을 위해를 QGraphicsView에 그림을 수 있습니다 내 대답을 확장하기 위해, IT/정보 업데이트를 수신하지 내를 QGraphicsView 객체를 다시 그려야 할 필요가 뷰포트입니다.

void QSchematic::mouseMoveEvent(QMouseEvent *event) 
{ 
    if(making_selection_box) 
    { 
     // get selection box 
     qDebug() << "updating selection box"; 
     curr_selection_end = event->pos(); 
     viewport()->repaint(box(drag_select_start, curr_selection_end)); 
    } 
    // propogate event 
    QGraphicsView::mouseMoveEvent(event); 
} 
+0

큰이 내가 찾던 그냥 뭐했다, 정말 그렇게 알고 도움 - QT는 QGraphicsScene/전망에 유물을 일으키는 원인이 된 이후, 나는 자연스럽게 그래서, 뷰포트 잊고, 무효화 및 업데이트 생각 나는 이것을 게시하기 전에 미쳐 버렸을지도 모른다는 게시를 기쁘게 생각합니다 ...! – osirisgothra