需求
实习末期接到一个项目,要我从后台发过来的HDF5文件中读取数据将其画成图表。一听,简单啊,Qchart画就好了啊,上手开干。一天后,HDF5是啥啊,咋读数据呢?怎么读字符串呢?于是开始全网找攻略,我发现非常非常的少,还好最后找到了文档,慢慢摸索终于解决了问题
具体要求
具体要求:从中台读取已经处理过用HDF5保存的一维数组,其中包括每个一维数据的名字集(单独一个结点)和一系列保存一维数组的结点,然后从中选取一个作为X轴,一个或多个作为Y轴完成表格的绘制,功能要求:多Y轴模式(2个以上)单Y轴模式 并能够相互切换,X轴Y轴单独缩放和同步缩放,框选放大,滚轮放大
难点
其中我觉得难点有以下几点:
1.从HDF5中读取数据(double和string)
2.实现框选放大
3.多Y轴和单Y轴的切换
4.其他不可预见的神奇Bug(折线阻挡了chartview的鼠标事件)
解决方法
其中着重讲一下HDF5文件读取的方法,因为我发现网上的资料不是很多,其他的就简单讲解一下,毕竟这些功能还是比较常规的,网上都有模板或者简单琢磨一下也能实现
从HDF5中读取数据(double和string)
首先我需要的功能只是读取,所有不涉及写回的问题,这里就不讲写回的方法了,但是后面会给一个网站,那个网站有相应的函数和相应的讲解(但是是全英文,用chrome应该问题不大)。好了不说了直接上代码
void read(hid_t file_id)
{
if(group.isEmpty())
{
return;
}
herr_t status;
hid_t name_dataset_id;
name_dataset_id=H5Dopen(file_id,group.toStdString().c_str(),H5P_DEFAULT);
int index=H5Dget_storage_size(name_dataset_id);
//hid_t dataType = H5Dget_type(name_dataset_id);//拿到HDF5中字符串的数据类型
std::vector<double> name_buffer(index/sizeof(double));
//std::vector<char> name_buffer(index);//字符串
status=H5Dread(name_dataset_id,H5T_NATIVE_DOUBLE,H5S_ALL,H5S_ALL,H5P_DEFAULT,name_buffer.data());
//status=H5Dread(name_dataset_id,dataType,H5S_ALL,H5S_ALL,H5P_DEFAULT,name_buffer.data());//字符串
data.clear();
for(int i=0;i<index/sizeof(double);i++)
{
data<<name_buffer[i];
}
status=H5Dclose(name_dataset_id);
status=H5Fclose(file_id);
}
最后就是前面说的那个网站(大家有什么问题还是以这个网站为准吧,我的代码只是一个参考,如有错误敬请谅解)
链接: https://support.hdfgroup.org/HDF5/doc/RM/RM_H5Front.html.
框选放大
这个功能非常的简单,因为chartview带了这个功能只需要要一行代码就能实现这个功能的开关,可全方位框选也可以实现仅对X或Y轴方向框选放大。
setRubberBand(QChartView::RectongleRubberBand);//全方位框选放大
setRubberBand(QChartView::HorizontalRubberBand);//水平框选放大
setRubberBand(QChartView::VerticalRubberBand);//垂直框选放大
setRubberBand(QChartView::NoRubberBand);//关闭框选放大
多Y轴和单Y轴的切换
这个比较简单,只需要添加/删除Y轴就行了,这里就不多介绍了,只是需要注意Y轴的范围,让曲线根据不同范围显示大小
其他BUG(折线阻挡了chartview的鼠标事件)
这个BUG我找了两天,可能你压根不会遇到,为什么呢?因为我看了另一个博主的代码,在画曲线时,用了OpenGL加速,可以使曲线更平滑,但是他会在曲线上生成一个widget阻挡鼠标点击事件,所以大家慎用。下面给打击看看QT官方文档的说法。
大家可以看到,他会生成一个QOpenGLWidget,这个真的有点坑,最开始我找了很多资料,发现别人曲线都能接收鼠标事件,而我就是被这个阻挡了,所以遇到同样问题的小伙伴可以看看是不是这个问题。