本来是想写一篇上位机通过串口接收数据并进行简单实时动态画图的,但是网上关于Qt串口接收数据的博客已经非常多了,且也会导致内容太多,显得复杂,如果需要串口收发数据例程,网上随便百度就能收到了,也可以下载我写的北斗/GPS双模定位上位机,这里主要介绍一下收到数据后的画图实现。
使用Qt绘制图形,首先需要了解Qt的窗口与视口的概念,理解Qt的坐标变换,然后学会掌握Qpainter这个类的使用就能实现基本的绘图功能了。下面一个实时绘制曲线图形的例子(坐标用应该直接使用一个Qpoint模板的列表表示比较好)。这里,实时数据只是由使用creatData函数产生,在实际工程中将数据改为读取实时数据即可。
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTimer>
#include <QList>
class Widget : public QWidget
{
Q_OBJECT
protected:
void paintEvent(QPaintEvent *);
public:
int m_count;
float x;
QTimer* m_Timer;
QList<float> xList;
QList<float> yList;
Widget(QWidget *parent = 0);
~Widget();
public slots:
void creatData();
};
#endif // WIDGET_H
源文件
#include "Widget.h"
#include <QPainter>
#include <QPointF>
#include <QPen>
#include <qmath.h>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
x = -10;
m_count = 0;
m_Timer = new QTimer(this);
m_Timer->start(10);
connect(m_Timer,SIGNAL(timeout()),this,SLOT(creatData()));
}
void Widget::creatData()
{
x += 0.2;
m_count += 1;
if(m_count%2)
{
xList.append(x);
yList.append(qSin(x));
}
else
{
xList.append(x);
yList.append(qSin(x));
update();
}
if(m_count == 100)
{
xList.clear();
yList.clear();
m_count = 0;
x = -10;
}
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPen pen;
pen.setColor(Qt::green);
pen.setStyle(Qt::SolidLine);
pen.setWidthF(0.05);
painter.setPen(pen);
painter.setViewport(50, 50, width()-100, height()-100);
painter.setWindow(-10, 2, 20, -4); // (-10, 2) (10, -2)
painter.fillRect(-10, 2, 20, -4, Qt::white);
painter.drawLine(QPointF(-10, 0), QPointF(10, 0)); // x
painter.drawLine(QPointF(0, 2), QPointF(0, -2)); // y
for(int i = 0; i < yList.count(); i++)
{
if(i == 0)
painter.drawPoint(QPointF(xList[i], yList[i]));
else
painter.drawLine(QPointF(xList[i-1], yList[i-1]), QPointF(xList[i], yList[i]));
}
}
Widget::~Widget()
{
}
主函数
#include <QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}