2017-02-19 4 views
0

ECG 애플리케이션을 개발 중입니다. 2 밀리 초마다 ECG 샘플을 얻습니다. 내 드로잉 메커니즘은 다음과 같습니다 : 1- 버퍼링 샘플 매 30ms마다 버퍼를 검사하고 샘플 (약 15 개 샘플)을 그립니다. 3- 모든 기간에 QPainterPath 사용.QG를 사용하는 ECG 신호 드로어

샘플 코드는 다음과 같습니다.이 코드에서 파일의 샘플을 읽습니다! 지금 내 질문은

class Widget : public QWidget 
{ 
    Q_OBJECT 
    int idx=0; 
    QTimer timer; 
public: 
    explicit Widget(QWidget *parent=0); 

    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; 
public: 
    QStringList list; 
    float x=0; 
    QPointF aa; 
public slots: 
    void changeT(){update();} 
}; 

2) widget.cpp

#include "widget.h" 
Widget::Widget(QWidget *parent) : QWidget(parent),aa(0,0) 
{ 
    connect(&timer,SIGNAL(timeout()),this,SLOT(changeT())); 
    timer.start(25); 
} 

void Widget::paintEvent(QPaintEvent *event) 
{ 
    QPainter painter; 
    painter.begin(this); 
    painter.setPen(QPen(Qt::black, 0.5, Qt::SolidLine, Qt::RoundCap)); 
    QPainterPath path; 
    path.moveTo(aa); 
    for(int i=idx; i<idx+25 ; i++) 
    { 
     QPointF bb(x, list.at(i).toInt()); 
     x+=0.25; 
     path.quadTo(aa,bb); 
     aa=bb; 
    } 
    idx+=25; 

    painter.drawPath(path); 
    QWidget::paintEvent(event); 
    painter.end(); 
} 

3) MAIN.CPP

#include "widget.h" 
bool ECG_data(QStringList& strings) 
{ 
    QFile file("/home/amvajnegar/ecg.txt"); 
    if (file.open(QIODevice::ReadOnly)) 
    { 
     QTextStream in(&file); 
     while(!in.atEnd()) 
     { 
      strings<< in.readLine(); 
     } 
     return true; 
    } 
    return false; 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    QStringList lst; 

    if(!ECG_data(lst)) 
    { 
     qDebug()<<"nothing!"; 
     return 0; 
    } 
    Widget wid; 
    wid.list = lst; 
    wid.show(); 
    return a.exec(); 
} 

을 : widget.h 파일

1)

1- 각 기간마다 새 샘플을 그릴 때 응용 프로그램에서 이전에 그려진 곡선 을 지우십시오! 그래서 저는 항상 커브의 짧은 부분만을 가지고 있습니다! 이 문제를 어떻게 해결할 수 있습니까?

내 임베디드 보드 CPU 사용량이 100 %입니다. 어떻게 줄일 수 있습니까? 예제 어떻게 사각형 사각형이나 다른 아이디어를 사용할 수 있습니까?

3- 이러한 곡선을 그리는 것이 더 좋은 메커니즘입니까? (나는 QCustomPlot 및 Qwt을 테스트>하지만 잘되지 않았다!)

여기 덕분에 내 ecg.txt 파일입니다.

+0

매번 QPainterPath를 다시 빌드하는 이유는 무엇입니까? 경로를 저장하는 것이 논리적이지 않으므로 올 때 지점을 추가하는 것이 좋습니다. 어쨌든 [Qt 차트] (http://doc.qt.io/qt-5/qtcharts-index.html)는이 작업에 가장 적합하다고 생각합니다. – folibis

+0

답장을 보내 주셔서 감사합니다. QPainterPath를 클래스 멤버 변수로 사용하면 내 첫 번째 문제가 해결되었고 지금은 올바른 그래프가 있습니다. 그러나 Qpainter가 최근의 곡선 부분을 업데이트한다고 어떻게 말할 수 있습니까? 나는 각 시대마다 화가가 구멍 경로를 그렸고 시간이 걸리고 CPU 사용량을 소비한다고 생각한다. 나는 단지 곡선에 마지막 25 개의 샘플을 추가하고 이전의 그려진 샘플에 대해서는 아무 것도하지 말라고 말하고 싶습니다. –

답변

0

해결책을 찾았습니다 : QWidget 업데이트 방법에 대한 경계 사각형을 설정해야했습니다. 이 함수는 사각형을 가져 와서 그 내부의 픽셀 만 업데이트합니다. 다음은 위젯 클래스에 대한 새로운 구현입니다. 주요 기능은 변경이 필요하지 않습니다.

class Widget : public QWidget 
{ 
    Q_OBJECT 
    int idx=0; 
    QTimer timer; 
    QPainterPath path; 
    QRect boundingRect; 
public: 
    explicit Widget(QWidget *parent=0); 

    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; 
public: 
    QStringList list; 
    float x=0; 
    QPointF aa; 
public slots: 
    void changeT(){update(boundingRect);} 
}; 

Widget::Widget(QWidget *parent) : QWidget(parent),aa(0,0) 
{ 
    connect(&timer,SIGNAL(timeout()),this,SLOT(changeT())); 
    timer.start(25); 
} 

void Widget::paintEvent(QPaintEvent *event) 
{ 
    QPainter painter; 
    painter.begin(this); 
    painter.setPen(QPen(Qt::black, 0.5, Qt::SolidLine, Qt::RoundCap)); 
    path.moveTo(aa); 
    boundingRect.setTopLeft(QPoint(x,0)); 
    boundingRect.setSize(QSize(30*0.25,500)); 
    if(idx+25>list.size()) 
     idx=0; 
    for(int i=idx; i<idx+25 ; i++) 
    {    
     const float y=list.at(i).toInt(); 
     QPointF bb(x, y); 
     x+=0.25; 
     if(x>750) 
     { 
      qDebug()<<"hi:" <<"y"<<y; 
      x=0; 
      path = QPainterPath(); 
      path.moveTo(x,y); 
      aa.setX(x); 
      aa.setY(y); 
      bb.setX(x); 
     } 
     path.quadTo(aa,bb); 
     aa=bb; 
    } 
    idx+=25; 

    painter.drawPath(path); 
    QWidget::paintEvent(event); 
    painter.end(); 
} 
0

놀라운 플롯 팅 라이브러리 - QCustomPlot을 사용할 수 있습니다.