2017-02-19 28 views
0

Я разрабатываю приложение ЭКГ. Он получает образцы ЭКГ каждые 2 миллисекунды. Мой механизм рисования выглядит следующим образом: 1- буферные образцы 2- проверка буфера каждые 30 мс и выборки образцов (около 15 образцов). 3- использование QPainterPath в каждом периоде.Ящик сигнала ЭКГ с использованием Qt

Мой пример кода приведен ниже, обратите внимание, что в этом коде я читал образцы из файла!

1) widget.h файл:

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(); 
} 

теперь мои вопросы:

1- Когда я рисую новые образцы за каждый период, приложение стирает предыдущую рисованную кривую! поэтому у меня всегда есть только короткая часть кривой! как я могу исправить эту проблему?

2- на моей встроенной плате Использование ЦП составляет 100%. как я могу уменьшить его? для пример, как использовать ограничивающий прямоугольник или любые другие идеи?

3- Это лучший механизм для построения таких кривых? (Я испытываю QCustomPlot и QWT> но не хорошо!)

вот мой ecg.txt файл спасибо.

+0

Почему вы каждый раз перестраиваете 'QPainterPath'? было бы логичным не хранить путь и, таким образом, просто добавить точку, когда она придет? В любом случае, я думаю, что [Qt Charts] (http://doc.qt.io/qt-5/qtcharts-index.html) является лучшим для этой задачи. – folibis

+0

Спасибо за ваш ответ. Использование QPainterPath как переменной члена класса разрешило мою первую проблему, и теперь у меня есть правильный граф. Но как я могу сказать, что Qpainter просто обновляет последнюю часть кривой? Я думаю, что за каждый период художник рисует путь дыры, и это требует времени и потребляет процессор. Я хочу сказать, что просто добавить последние 25 образцов на кривой и ничего не делать для предыдущих обращений. –

ответ

0

Я нашел решение: Мне пришлось установить ограничивающий прямоугольник для метода обновления QWidget. Эта функция принимает прямоугольник и обновляет только пиксели внутри него. Вот мои новые реализации для класса Widget. Основная функция не требует каких-либо изменений:

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.