用qcustomplot类画实时曲线replot()速度跟不上硬件采集数据的速度怎么办

sinat_35774390 2016-08-06 08:33:48
我现在在做一个界面,实时显示从硬件上采集得到的数据,画成曲线或者散点。最近在论坛中朋友的帮助下有了一点思路:创建一个子线程,在子线程中采集硬件数据,在主线程中用qcustomplot画图,子线程中发送数据信号,触发主线程的槽函数,在主线程的槽函数中画图。但是现在又出现了一个问题,就是在我做的这个界面上实时画图的速度跟不上硬件采集数据的速度。因为我的硬件有一个LCD屏幕,在这个屏幕上已经实现了实时画数据。两个一对比就发现qt界面上画图速度跟不上LCD上的画图速度。我的硬件采集数据的速度大概是每15ms采集一个点,界面上一次画127个点。而且感觉我的画图部分的代码也不多啊。。请问该怎样处理才能提高qcustomplot的画图速度?
下面是我的简略的代码,布局的代码没写,代码写得乱,请各位大神将就着看。。
[code=c++]
Widget.h
class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

public slots:
void readData(unsigned int ledinx,int num);

private:
Ui::Widget *ui;
QCustomPlot *myplot;
Thread *myThread;
double key;
double data;
void realtimeDataSlot();
}


Widget.cpp
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui -> setupUi(this);
key = 0;
data = 0;

myplot = new QCustomPlot;
myplot -> addGraph(0);

myThread = new Thread;
connect(myThread,SIGNAL(UpdateSignal(unsigned int ,int)),this,SLOT(readData(unsigned int,int)));

myThread -> start();
}

void Widget::readData(unsigned int ledinx,int num)
{
key = ledinx;
data = num;
realtimeDataSlot();
}

void Widget::realtimeDataSlot()
{
myplot -> graph(0) ->removeData(key);
myplot -> graph(0) -> addData(key,data);

myplot -> replot();
}
[/code]
...全文
8023 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
TianCaiTang 2020-04-15
  • 打赏
  • 举报
回复
楼主,能否分享一下代码,我是名Qt小白,现在想把AD采集到的信号实时显示出来,所以想参考你的代码学习一下。邮箱:1005605205@qq.com 不胜感激!
m0_46171324 2020-03-23
  • 打赏
  • 举报
回复
楼主,你好,我最近也在学习AD采集的这个,能方便分享一下源码吗,万分感谢。邮箱2263938707@qq.com
LittleFly4398 2018-08-22
  • 打赏
  • 举报
回复
嗯,感觉楼主调用 replot(QCustomPlot::rpQueuedReplot) 的方法也是可行的。读了一下说明,感觉和QWidget的repaint()与update()的区别挺像的。
另外说一下我的做法,我的数据采集和绘图是分离的,因为数据采集和绘图是两个不同的功能。我之前以及目前都是通过QTimer的响应槽函数来replot()的,因为QTimer的槽函数不会被新的timeout打断,而且经过测试,QTimer触发时间小于槽函数运行时间时,并不会导致槽函数响应次数累积。采用QTimer触发绘图的方法,绘图的刷新率是动态变化的,而且性能好一点平台的刷新率会比较高(不会超过QTimer设定的触发周期对应的刷新率)。
然后换一个角度说一下replot时间要求的问题,目前大部分的显示器的刷新率都是60hz,因此你replot()的刷新率达到60就差不多了,再上去也看不出什么效果。
qq_39657476 2018-07-30
  • 打赏
  • 举报
回复
新版本更新后没那么麻烦了,可以看一下官方给出的帮助文件
void QCustomPlot::replot ( QCustomPlot::RefreshPriority refreshPriority = QCustomPlot::rpRefreshHint)
Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is refreshed with the new buffer contents. This is the method that must be called to make changes to the plot, e.g. on the axis ranges or data points of graphs, visible.

The parameter refreshPriority can be used to fine-tune the timing of the replot. For example if your application calls replot very quickly in succession (e.g. multiple independent functions change some aspects of the plot and each wants to make sure the change gets replotted), it is advisable to set refreshPriority to QCustomPlot::rpQueuedReplot. This way, the actual replotting is deferred to the next event loop iteration. Multiple successive calls of replot with this priority will only cause a single replot, avoiding redundant replots and improving performance.

Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the QCustomPlot widget and user interactions (object selection and range dragging/zooming).

Before the replot happens, the signal beforeReplot is emitted. After the replot, afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite recursion.

If a layer is in mode QCPLayer::lmBuffered (QCPLayer::setMode), it is also possible to replot only that specific layer via QCPLayer::replot. See the documentation there for details.
也就是说,把重画的频率高的部分的replot();改成replot(QCustomPlot::rpQueuedReplot);就可以了
sawyer24 2018-04-10
  • 打赏
  • 举报
回复
请问楼主:connect(myThread,SIGNAL(UpdateSignal(unsigned int ,int)),this,SLOT(readData(unsigned int,int))); 中的子线程的UpdateSignal(unsigned int ,int)信号你是如何定义的?
sawyer24 2018-04-02
  • 打赏
  • 举报
回复
楼主,能否分享一下代码,我是名Qt小白,现在想把AD采集到的信号实时显示出来,所以想参考你的代码学习一下。邮箱:2210605591@qq.com 不胜感激!
个何必 2017-12-14
  • 打赏
  • 举报
回复
谢谢楼主
KeKiKeKi 2017-02-19
  • 打赏
  • 举报
回复
其实从你硬件传回数据也是需要耗时的,LCD屏幕和上位机不同步也正常把
sinat_35774390 2016-08-09
  • 打赏
  • 举报
回复 4
谢谢各位朋友了!最终我是这样解决的,把realtimeDataSlot()函数中的addData和replot分离,写在两个函数里,然后每采集一个点执行一次addData,但是每采集四个点才执行一次replot,这样把重画的频率降低,replot的速度就能跟上硬件采集数据的速度了。虽然并没有真正做到实时显示数据,但是因为硬件采集数据的速度太快了,所以隔4个点再replot看起来也像是实时显示一样。
内容概要:本文围绕不确定环境下的多式联运路径优化问题展开研究,提出并实现了基于AFO算法、遗传算法(GA)和粒子群优化算法(PSO)的三种智能优化方法,并借助Matlab平台完成算法编程与仿真。研究构建了考虑时间、成本、转运风险等多重不确定因素的路径优化模型,系统比较了AFO、GA、PSO三种算法在收敛速度、全局寻优能力和稳定性方面的表现,同时引入Matlab自带的全局优化搜索器作为基准对照,深入分析各算法在复杂物流网络中的适用边界与性能差异。研究表明,AFO算法在解决此类组合优化问题时展现出更快的收敛效率和更强的局部规避能力。; 适合人群:具备一定Matlab编程基础与运筹优化知识,从事物流工程、交通运输规划、智能算法开发等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多式联运、综合货运网络中的路径决策支持系统构建;②为不确定性条件下复杂路径规划问题提供智能算法选型依据与技术实现方案;③支持科研人员复现主流优化算法并开展横向性能对比实验,推动算法改进与实际落地。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点理解目标函数设计、约束条件处理及参数敏感性分析部分,可通过调整问题规模与算法参数进行对比实验,进一步拓展至动态路径规划或大规模网络优化等延伸场景。
内容概要:本文研究了基于QLearning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,通过Matlab代码实现了控制算法的仿真验证。该方法融合强化学习的在线自适应能力与传统PID控制的稳定性优势,利用QLearning算法动态优化PID控制器的比例、积分、微分参数,以应对水下复杂流体环境、模型不确定性及外部干扰等挑战,从而提升AUV轨迹跟踪的精度、鲁棒性与动态响应性能。文中系统阐述了AUV的六自由度非线性动力学建模过程、QLearning算法的状态空间与动作空间设计、奖励函数构造及训练机制,并详细说明了PID参数自整定的闭环控制架构。仿真结果表明,相较于传统固定参数PID控制器,该智能控制策略在多种工况下均展现出更优的控制效果,有效抑制了超调,加快了响应速度,并增强了抗干扰能力。; 适合人群:具备自动控制理论、强化学习基础及Matlab/Simulink仿真能力,从事水下机器人、智能控制、海洋工程、自动化等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于AUV、UUV等无人水下平台的高精度自主导航与运动控制;②为解决非线性、强耦合、时变系统的控制器参数自适应整定问题提供智能化解决方案;③作为强化学习与经典控制理论深度融合的技术范例,推动智能控制算法在海洋装备中的工程化应用。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点剖析QLearning的状态-动作-奖励机制设计、PID参数更新逻辑及仿真对比实验结果,有条件者可在更复杂的动力学模型或实际硬件平台上进一步验证与优化算法性能。

21,499

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧