Part 0:基础知识
以下内容可能会对读者更好的理解Qt存在帮助,可以按需阅读。
Qt绘图基础知识:https://blog.csdn.net/gongdiwudu/article/details/125256206
Qt基本绘图对象:https://blog.csdn.net/qq_29331365/article/details/105691223
QtCharts简介:https://blog.csdn.net/qq21497936/article/details/106528645
创建一个QtCharts图表:https://blog.csdn.net/qq_43627907/article/details/124520432
Part 1:QtCharts基础功能开发
QtChart是Qt为开发者提供的一种功能强大的图标控件集,可以快速绘制折线图、柱状图、饼图等多种图形,其易于使用的特点为广大开发者所青睐,接下来我们将以此为基础为大家展示如何搭建QtCharts控件。
Step 1:新建QtCharts控件容器
在主界面创建一个Graphics View控件,并命名为OscView。此Graphics View控件不能直接作为QCharts的实现载体,故需要新建一个C++类。
Step 2:新建用于QtCharts的派生类
- 在菜单栏打开“File->New File or Project”
- 左侧选择“C++”,右侧选择“C++ Class”,创建一个空白类
- 点击“Choose”之后,输入类名“QChartView”,并选择基类为“QWidget”,注意更改存储路径为当前文件夹。
- 按照默认设置,将新建立的类添加至当前工程,之后点击“Finish”
Step 3:将步骤1中的OscView与步骤2中的QChartView类建立联系(提升)
- 在界面设计页面右键OscView,选择“Promote to ...”
- 在弹出的窗口中,按照步骤2中所创建类的信息,为OscView执行“提升”
Step 4:为mainwindow.h加入头文件并引用QCharts命名空间
- 添加头文件
#include <QtCharts>
- 引用命名空间
using namespace QtCharts;
- 在MainWindow的私有变量列表中添加趋势线和图标指针
QLineSeries* series;
QChart* chart;
Step 5:为QCharts图表加入初始化代码,并简单配置
在mainwindow.c的构造函数中加入如下代码:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
myserial = new QSerialPort();
QObject::connect(myserial, &QSerialPort::readyRead, this, &MainWindow::on_SerialRecv);
ui->comboBoxSpeed->setCurrentIndex(9);
series = new QLineSeries();
series->setName("Test Series");
qreal SyncArray[]={0x53,0x59,0x4E,0x43,0x00,0xFF,0x00,0xFF};
QList<QPointF> points;
for(int i = 0; i < 8; i++)
points.append(QPointF(i, SyncArray[i]));
series->replace(points);
chart = ui->OscView->chart();
chart->addSeries(series);
chart->createDefaultAxes();
chart->setTitle("Test Chart");
ui->OscView->setRenderHint(QPainter::Antialiasing);
}
此段代码的主要功能为:
创建趋势线(Series)
为趋势线命名
为趋势线添加点集
获取OscView的绘图对象
为绘图对象添加趋势线
为绘图对象创建默认坐标轴
为绘图对象设置标题
开启OscView的抗锯齿模式
Step 6:编译运行,查看效果
前面的步骤为界面添加了一条趋势线,并将“同步序列”的数据点集添加进去,运行成功后会出现如下运行结果。
Tips:上述步骤实现的界面是“绝对位置”定位,在窗口大小变化时,界面中各个组件的大小不会改变,会出现很大的白边区域,接下来将简单介绍如何通过格栅布局实现控件大小动态改变。
- 右键串口选择框,选择“Size Constricts->Set Minimum Size”
- 添加一个“Vertical Spacer”
- 选择界面布局为“格栅布局”
此后再拖动边沿时,界面上的各个组件尺寸就会跟随界面自动变化,使得界面上不会存在多余的空白区域。
Part 2:QtCharts示波器显示功能开发
前文中已经讲解过如何将STM32示波器的数据通过串口解包,也介绍过如何将数据添加至QtCharts中,本节将把二者结合,实现基础的示波功能。
在mainwindow.c的串口接收函数中加入如下代码:
void MainWindow::on_SerialRecv(void)
{
static QByteArray RecvBuff;
if(myserial->isOpen())
{
QByteArray QBArecv =myserial->readAll();
RecvBuff.append(QBArecv);
char SyncArray[]={0x53,0x59,0x4E,0x43,0x00,0xFF,0x00,0xFF};
QByteArray Sync=QByteArray(SyncArray,8);
if(RecvBuff.indexOf(Sync)!=-1)
{
QByteArray Packed=RecvBuff.left(RecvBuff.indexOf(Sync)+8);
RecvBuff=RecvBuff.mid(RecvBuff.indexOf(Sync)+8);
QBArecv=Packed;
QString Recv="";
if(1)
{
QString Temp;
int cnt=0;
QList<QPointF> points;
foreach(QChar dat,QBArecv)
{
Recv+=Temp.sprintf("%02X ",(unsigned int)dat.unicode());
if(cnt<(QBArecv.length()-8))points.append(QPointF(cnt++,(unsigned int)dat.unicode()));
}
series->replace(points);
chart->axisX()->setRange(0,cnt-1);
}
else Recv+=QString::fromLocal8Bit(QBArecv);
qDebug()<<Recv;
qDebug()<<"Lenth="<<Packed.length();
}
}
}
本段函数的主要功能是在原有串口数据包解析的基础上,针对数据包中的每一个字节,将之作为数据中的一个数据点显示在QtCharts中(符合现在定义的简单数据格式,后期会使用更为复杂的数据格式,目前先以此格式简单测试)。
编译运行后,效果如下图所示:
整体效果图如下图所示:
Part 3:STM32示波器上位机配置功能开发
STM32示波器支持如下格式的命令参数设置,可以用于修改示波器运行参数:
<命令集>:<命令>.参数;<\r\n>
目前支持的命令有:
system: SetTime.<时间参数>; <\r\n>
function: TrigLevel.<触发电平>; <\r\n>
function: SmitLevel.<施密特触发电平差值>; <\r\n>
function: SimpleRate.<采样率 >; <\r\n>
function: WindowLenth.<采样窗长>; <\r\n>
function: OscSync.<同步模式>; <\r\n>
function: OscMode.<运行模式>; <\r\n>
接下来将针对采样率和采样窗长的控制方式进行详细介绍,以点带面,展示指令发送过程。
Step 1:按照下图为示波器界面添加分组框和下拉框
Step 2:为两个下拉框分别设置可选参数
下拉框1:comboBoxBuffer
参数:128、256、512、1024、2048、4096
下拉框1:comboBoxSampleRate
参数:500、1k、2.5k、5k、10k、25k、50k、100k、250k、500k、1M
Step 3:为采样窗长下拉框(上)链接槽函数
按照标准的槽函数添加步骤,为采样窗长下拉框添加槽函数,函数选择“currentIndexChanged(QString)”,此时可以通过在槽函数中将文本转换为数值直接发送给STM32。
Step 4:编写槽函数
void MainWindow::on_comboBoxBuffer_currentIndexChanged(const QString &arg1)
{
QString Tx;
Tx.sprintf("function:WindowLenth.%d;\r\n", (int)arg1.toInt());
if(myserial->isOpen())myserial->write(Tx.toLocal8Bit());
}
上述代码主要功能为:将下拉框中的文本转换为Int类型,然后格式化输出至Tx字符串,并通过串口发送给STM32示波器。
Step 5:为采样速度下拉框(下)链接槽函数
按照标准的槽函数添加步骤,为采样窗长下拉框添加槽函数,函数选择“currentIndexChanged(int)”,此时需要通过在槽函数中建立查找表才能选择合适的数据发送给STM32。
Step 6:编写槽函数
void MainWindow::on_comboBoxSampleRate_currentIndexChanged(int index)
{
int SampleMap[]={500,1000,2500,5000,10000,25000,50000,100000,250000,500000,1000000};
QString Tx;
Tx.sprintf("function:SimpleRate.%d;\r\n", SampleMap[index]);
if(myserial->isOpen())myserial->write(Tx.toLocal8Bit());
}
上述代码主要功能为:将下拉框的索引值通过查找表SampleMap转换为实际采样率,然后格式化输出至Tx字符串,并通过串口发送给STM32示波器。
Step 7:运行测试
点击界面左下角的绿色运行三角(无debug标志),即可编译生成工程查看效果。
Part 4:Qt示波器实机演示效果
此示波器的基础功能到此已经开发完毕,后续将会从触发、网络通信等方面进行完善,以下是将旭日X3派接上触摸屏后的运行效果:
可以直接触摸界面上的按钮、下拉框实现示波器配置,并可以从左侧大屏上观察到波形情况。
Part 5:源码下载
本章节中提到的代码可以从如下链接下载:
链接:https://pan.baidu.com/s/1t4DzPNG56PBeH8chUSD-lA?pwd=Yuki
提取码:Yuki
评论(0)
您还未登录,请登录后发表或查看评论