2012-04-15 1 views
1

Qt 기반 응용 프로그램 (실제로 PyQt에서 작동하지만 여기서는 관련이 없다고 생각합니다.) 중 일부는 잠재적으로 연속적인 플로트 데이터를 실시간으로 그래프에 표시합니다.Qt/PyQt - 자주 그림 그리기가 올바르게 실행되지 않습니다.

들어오는 데이터를 버퍼링하는 QWidget에서 파생 된 클래스를 생성하고 30ms마다 그래프를 플롯 (기본값)하여 구현했습니다. __init__()에서 QPixmap이 생성되고 모든 틱이 QTimer 인 경우 (1) 그래프가 새로운 데이터가 차지하는 픽셀 수만큼 왼쪽으로 이동 한 경우, (2) 공간에 그려진 사각형이 (3))는 다음과 같이 (삭감, 포인트 플롯, (4) update() 위젯에서 호출 :

p = QtGui.QPainter(self) 
    p.drawPixmap(0, 0, self.graphPixmap) 

로 :

# Amount of pixels to scroll 
    scroll=penw*len(points) 

    # The first point is not plotted now, so don't shift the graph for it 
    if (self.firstPoint()): 
     scroll-=1 

    p=QtGui.QPainter(pm) 
    # Brush setup would be here... 

    pm.scroll(0-scroll, 0, scroll, 0, pm.width()-scroll, pm.height()) 
    p.drawRect(pm.width()-scroll, 0, scroll, pm.height())   

    # pen setup etc happens here... 

    offset=scroll 

    for point in points: 
     yValNew = self.graphHeight - (self.scalePoint(point)) 

     # Skip first point 
     if (not(self.firstPoint())): 
      p.drawLine(pm.width()-offset-penw, self.yVal, pm.width()-offset, yValNew) 

     self.yVal = yValNew 
     offset-=penw 

    self.update() 

마지막으로, paintEvent는 단순히 위젯에 픽스맵을 그립니다 지금까지 볼 수 있듯이, 이것은 데이터가 매우 빨리 수신 될 때 올바르게 작동합니다 (즉, 전체 그래프가 pl 위젯이 특정 크기 (약 700px)보다 크면 700px 영역의 왼쪽에있는 모든 것이 상당히 뒤 떨어진다. 이 비디오에서 가장 잘 나타납니다 : http://dl.dropbox.com/u/1362366/keep/Graph_bug.swf.html (낮은 프레임 속도로 인해 비디오가 약간 뒤떨어 지지만 효과가 나타납니다)

어떤 아이디어로 인해 시도 할 수 있었습니까?

감사합니다.

답변

0

이것이 문제가되는지 확실하지는 않지만 적어도 기여할 수 있다고 생각합니다.

는 비동기 호출이므로 나중에 일정 이벤트 루프에 다시 도달 할 때 페인트 이벤트가 발생합니다. 따라서 픽스맵을 수정할 때와 실제로 paintEvent에서 사용될 때의 동기화 문제 때문에 드로잉에 문제가 있는지 궁금합니다. 거의 정확한 코드가 작동하기 위해 필요한 것은 페인트 이벤트의 자물쇠 인 것 같지만 꽤 나쁜 소리입니다.

self.update() 
QtGui.QApplication.processEvents() 

확인하십시오 그것을 해결하지 않습니다,하지만 시도는 그 가치 : 빠른 테스트에 대한

, 당신은 당신의 전화가 업데이트 후 바로 세척하는 이벤트 루프를 강제로 시도 할 수 있습니다.

self.repaint() 내가 당신에게 비슷한 질문을 발견 사람 :

이것은 실제로 당신이 제어 프레임 속도를 사용하여 "애니메이션"을하고 있기 때문에 적절한 상황이, repaint()를 사용하여 직접 페인트 이벤트를 일으키는 원인이 될 수 있습니다 실시간으로 심장 모니터를 그래프로 그려보십시오. http://qt-project.org/forums/viewthread/10677
어쩌면 당신은 비슷한 코드를 재구성 해 볼 수 있습니다. 페인팅을 두 단계로 나누는 대신 QLabel을 디스플레이 위젯으로 사용하고 Pixmap을 QLabel로 설정 한 다음 widget.update()에 대한 호출 대신 전체 그래프를 즉시 페인팅합니다.

관련 문제