2008年10月
第45卷增刊2
四川大学学报(自然科学版)
JournalofSichuanUniversity(NaturalScienceEdition)
oCt.2008
V01.45
Suppl.2
文章编号:0490-6756【2008)Suppl-0061…04
实时数据曲线绘制的Qt编程实现
杨盛毅1,文
方1,师娇2
(1.贵州大学电气工程学院。贵阳550003;2.北京理工大学宇航科学技术学院,北京100081)
摘要:动态绘制和显示实时数据曲线是工业测控系统中一项重要功能.本文提出了一种利用Qt编程动态绘制实时数据曲线的方案,解决了由于绘制时间较长而无法满足实时显示要求的问题,并通过实例介绍了其具体实现方法.实践证明该绘制方案能满足实时监控的要求.关键词:测控系统;实时数据曲线;Qt
中图分类号:TP311
文献标识码:A
Realizationof
real_time
data
curve
drawingbaseon
Qtprogramming
YANGSheng—Yil,WENFan91,SHIJia02
(1.CollegeofElectricEngineering,GuizhouUniversity,Guiyang550003,China,
2.SchoolofAerospaceScienceand
Engineering.BeijingInstituteofTechnology,Beijing100081,China)
Abstract:Dynamicdrawingandshowingthereal—timedata
curve
is
an
importantfunctionoftheindustri-
altestingandcontrollingsystem.Amethodofdynamicdrawingandshowingthereal—timedatacurve
based
on
Qtprogrammingisintroducedinthispaper,anditsolvestheproblemthatthedrawingtimeis
too
long
to
showthedata
curve
intime.anditisillustratedby
a
integralexample.Itprovedthatthe
programcouldsatisfythereal—timecontrolrequirements.
Keywords:testingandcontrollingsystem,real—timedatacurve,Qt
1
引言
工业测控系统中,常用动态实时数据曲线来监测某些量在工作环境变化时的控制稳定性.从而动态绘制实时数据曲线成为测控软件开发中的重要一环,而动态绘制实时数据曲线存在由于绘制时间较长而无法满足实时显示要求、绘制数据量大、动态平滑显示等问题.Qt是由挪威Trolltech公司开发的一个跨平台的C++图形应用程序开发框架,基于“信号一槽”的通讯机制,并具有高度模块化、可重用性好、运行速度快、可移植性好等特点,对于用户开发来说是非常方便.目前主要用于Linux下的开发.同时Qt还是跨平台的,它使得跨平台软
件编程直观、简易和方便.但同其它编程工具一样,Qt也不具备直接的动态曲线绘制能力,必须借助一些编程技术来实现.我们提出了一种利用Qt编程动态绘制实时数据曲线的方案,解决了由于绘制时间较长而无法满足实时显示要求的问题.
2
实时数据曲线绘制的基本思路
所谓数据曲线,实质上是由许多直线首尾相连
组合而成,在绘图区中用直线连接两数据点来实现,通过setWindow函数可设定绘图区大小及绘图原点坐标.数据曲线上前一时刻数据点通常在曲线上最左端显示,随着时间推移,整条曲线自右向左移动.实现曲线的动态平移必然涉及到曲线的消
收稿日期:2008-08-31
作者简介:杨盛毅(1986一),男,布依族,贵州平塘人,在读硕士研究生,研究方向为计算机测控技术.
62
四川大学学报(自然科学版)增刊2
隐或重绘,常用的两种绘图方式为:一种方式是将画线对象的属性设为与或,然后在原位置重绘曲线,单一背景色的情况下,也可直接用背景色重绘曲线,实现曲线的动态效果;另一种方式是通过调用API函数BitBh实现曲线的平滑移动.
上述两种常用绘制方案,虽然解决了大数据量、动态平滑显示的问题,但实时性不佳,所以本文提出一种新的数据绘制方案.本方案中数据曲线上各点纵坐标反映实时数据的大小,通过记录次新点数据,并更新最新点数据,在定时器中使用Qwid—get类中scorll函数定时将图象向左卷动一定像素,卷动后scroll函数发送绘制事件.绘制事件中,只绘制由于卷动而空出的区域,利用drawLine函数将最新数据点与次新数据点以直线相连,即可实现实时数据曲线自右向左的平滑移动效果.
绘图区内实时曲线的数据量由scroll函数卷曲的像素值所决定,即卷曲的像素越多,数据量越少,卷曲的像素越少,数据量越多.条件允许时,应增加实时曲线的数据量,更有利于监控现场环境的变化趋势.同时为了避免绘图区数据点过于拥挤,可在当前绘图区显示一部分数据曲线,通过滚动条查看数据曲线的其它部分.3
实时曲线绘制的实时性
由于绘制时间较长而无法满足实时显示的要
求,是实时数据曲线绘制中存在的普遍问题.我们提出的方案,由于每次绘制时所需绘制的数据极I
(2)声明模块级变量
int
myTimerld;
intxpos;
intdisplayDatalypos;intdisplayDatafyposintdisplayDatachargebool
Close
(3)在Drawer类构造函数中添加代码
setBackgroundColor(black)myTimerld=0xpos=O
displayDatalcharge-----0
(4)为公有槽openDraw和closeDraw添加代码
openDraw:Close—TURE;
myTimerId—startTimer(30):
少,所以能有效提高绘制的实时性.在程序中,通过调用函数QueryPerformanceCounter获取计算机定时器的当前值,并调用函数QueryPerformance—Frequency获取计算机定时器的频率,通过计算绘制后计算机定时器的值与绘制前计算机定时器的值之差,再乘以定时器频率,即可得到绘制所花费的时间.目前常用PC的定时器频率在3.5×
106
Hz左右,所以采用该方法计算绘制所花费的时
间可以精确到0.28x10一S.通过实验,得到本文所述方案的平均绘制时间为173ns,而采用双缓冲绘制方案的平均绘制时间为1.72ms,由此可见,我们提出的方案有效的提高了绘制的实时性.
4程序实例
此处以一个完整的程序实例说明实时数据曲线的绘制方法.
(1)首先构造实时绘图类
创建Drawer类,它以公有方式继承于QWid~get.由于该类定义了信号和槽,所以必须将Q—OBJECT宏置于类定义的开始处.在类中分别创建公有槽openDraw和closeDraw,前者是开始绘制控制函数,后者是停止绘制控制函数.再创建公
有函数drawCurves和drawGrid,前者用于绘制实时曲线,后者用于绘制网格.最后重载事件paint—Event和timerEvent,前者用于实现绘制事件,后者用于实现定时功能.
//定义QObjeet定时器//实时数据曲线的横坐标//实时数据啮线的最新点数据//实时数据曲线的次新点数据
//最新点数据向次新点数据的中转变量//绘制与初始化判断逻辑变量
//将绘制区域的背景设置为黑色//设置定时器的初值
//设置实时数据曲线的横坐标的初值//设置实时数据曲线中转变量的初值
//设置为绘制
//设置每30ms产生一个定时事件
2008年杨盛毅等:实时数据曲线绘制的Qt编程实现
63
closeDraw:Close=TURE;
killTimer(myTimerld);
update();
(5)为公有函数drawCurves和drawGrid添加代码
drawGrid(QPainter&painter):
painter.setPen(green);
for(intu=0;u<300;U++){
//设置为初始化//设置停止定时器//重新绘制绘图区
//将画笔颜色设置为绿色//绘制网格的纵轴
if(u%50---------0){painter.drawLine(--4,u,0,u);painter.drawLine(--4,一u,0,--u);))if(xpos%10=一O|Ixpos一一O){
//绘制网格的横轴
painter.drawLine(--4,500,一4,--500);)++xpos;drawCurves(QPainter&painter):
painter.setPen(red);
displayDatafypos=displayDatacharge;
displayDatacharge=displayDatalypos
//将画笔颜色设置为红色
//将最新点数据通过中转变量传递给次新点
painter.drawLine(--4,一displayDatafypos,0,一displayDatalypos);
将最新点数据和次新点数据
用直线连接
(6)重载事件paintEvent和timerEvent
paintEvent(QPaintEvent*event):QPainterpaint(this);
paint.setViewport(0,0,width(),height());
paint.setWindow(QRect(一700,一250,701,501));
if(Close=一TRUE){
drawGrid(paint);drawCurves(paint);
}else(xpos-----;displayDatalcharge=;}
timerEvent(QTimerEvent*event):if(event一>timerld()一=myTimerld){scroll(一5,O);
displayDatallypos—rand()%150;)else{QWidget::timerEvent(event);)
(7)新建一个工程
在Forml窗体上添加一个Drawer类的对象drawer,在其中绘制实时数据曲线;创建两个命令按钮:Begin—pushButton和Stop—pushButton.并用下列代码将对应的信号和槽连接起来.
connect(Begin_pushButton,SIGNAL(clicked
()),drawer,SLOT(openDraw()));将开始键的单击信号与drawer对象的openDraw槽连接在一
connect(Stop—pushButton,SIGNAL(clicked
//设置绘制设备的物理坐标//设置画笔的逻辑坐标
//判断是绘制曲线还是要初始化//绘制网格//绘制曲线
//实时数据曲线的横坐标的初始化//实时数据曲线中转变量初始化
//判断是否是我们需要的定时器//向左卷动5个像素//装人最新数据
//若不是需要的定时器,将它传递给基类
()),drawer,SLOT(closeDraw()));将停止键的单击信号与drawer对象的closeDraw槽连接在一
程序编译运行后的效果如图1所示,绘图窗口中的数据曲线每隔一个定时时间自右向左移动设定像素.当然,为了界面的美观和读数方便,可在绘图窗口周围加上坐标刻度等,本文的程序示例主要实现动态绘制实时数据曲线,其它功能的实现程序
日…女学学报(自然科学版)增刊2
5结语
动惫绘制寅时数榔曲线是测控系统中的重要功能模块,我们提出了一种利朋∞t编程动态绘制实时数据曲线的方案,解陡r由于绘制时问较K而
无法满足实时显示要求的问题,具有一定实用价值文中程序的数据均是随机模拟的,实际测控系统中只需用采集输^数据或控制输出数据替换掉
模拟数据即可程序圻例仅在同卟绘田窗口中动
态绘制了单通道数据曲线.如需同时显示N通道数据曲线,H需将文中程序作简单扩充.具体宴现程序略
参考文献:
r1]GaⅫllnBlarKhctteMarkSummerlieldC十一GUI
P
rog……g
wln味3
l
st
Edition[M
BHtain.
I?carsonEdoca[ionZ003
f2]{¥《Lir:uxⅢ自≈§镕口自&#R[M]Jbg.#
{&mⅡ200i
f37“自,《■cf+日=≈g&if[M]J匕日Ⅺ4^{
&m#.200l
L4JⅫ*#?∞i%LimJx&境&日々*&#《[M]“
《:n#In&mir.2005
实时数据曲线绘制的Qt编程实现
作者:杨盛毅,文方,师娇
作者单位:
杨盛毅,文方(贵州大学电气工程学院,贵阳 550003,师娇(北京理工大学宇航科学技术学院,北京 100081
本文链接:https://www.sodocs.net/doc/9a2702748.html,/Conference_6868561.aspx