在vb中绘制实时曲线是比较难的,一般要应用第三方控件或是windows api函数来完成,但是如果你对实时曲线的要求不是很高,只要能表示出当前的一般情况的话,我们可以直接应用vb提供给我们的空间来完成.
原则上讲,直接在form里绘制曲线都是可以的,msdn上面很多例程就是直接在form里面绘制图形的,form作为绘制图形的容器,不过一般应用中form中不可避免的会有很多其他控件,所以我们选择picturebox作为绘制曲线的容器.
实时曲线的绘制一般借助于timer控件来完成,使用timer控件,定期将串口或是其他仪器中监测到的数据送往picturebox1,而曲线的绘制一般画成折线图,采用picturebox1的line方法绘制.具体实现如下:
1.选择需要显示的窗体picture1,加入图片框picture1,根据实际需要设置图片的大小并移到合适的位置,并在图片的外面画好量程----时间坐标系;然后加上timer控件以及两个commandbutton,界面就基本设置好了.
2.建立坐标系,根据picture1的大小和高度设置画出坐标系的x轴和y轴:
picture1 .scalemode = 1 ‘以vb的基本单位作为建立坐标轴以及绘制图形的单位;
picture1.refresh
picture1.currentx = picture1.scaleleft +100
picture1.currenty = picture1.scaletop
picture1.print picture1.scaleheight - 100
picture1.line(picture1.scaleleft+100,picture1.scaletop+100)-(picture1.scaleleft+100, picture1.scaleheight - 100)
picture1.currentx = picture1.scaleleft +100
picture1.currenty = picture1.scaleheight
picture1.print “(0,0)”
picture1.line (picture1.scaleleft + 100, picture1.scaleheight - 100)-(picture1.scalewidth - 100, picture1.scaleheight - 100)
picture1.currentx = picture1.scalewidth
picture1.currenty = picture1.scaleheight
picture1.print picture1.scalewidth-100
picture1.autoredraw = true ‘必要时,用存储在内存中的图象进行重绘
3.绘制曲线并保存,我们这里以正弦曲线作为绘制曲线的数据来源,具体应用是可以采用由串口或其他仪器采集得到的数据.首先我们绘制一条中线,然后在timer控件的time事件中绘制曲线:
picture1.line (picture1.scaleleft, cint(picture1.scaleheight / 2))-(picture1.scalewidth, cint(picture1.scaleheight / 2)) ‘绘制中线
private sub timer1_timer()
dim y1 as integer
y1 = cint(sin((x - picture1.left) / 20 / 180 * pi) * picture1.scaleheight / 2)
y1 = cint((picture1.scaleheight + 1000) / 2) - y1
picture1.line (x, y)-(x + 20, y1)
x = x + 20
y = y1
if x >= picture1.scalewidth then
savepicture picture1.image, "c:\sin.bmp" ‘保存图画,可以根据实际需要命名图片
x = 0
y = picture1.scaleheight / 2
picture1.cls ‘清屏重画
end if
end sub
从上面的过程可以看出,其实对于要求不高的实时曲线的绘制还是比较简单的,在这里我采用的是清屏重画图像,如果要实现图像往左移动,图像仍然保留的效果,可以采用windows的bitblt函数,可以让图像每次移动一个象素或是多少个twip,具体实现可以参见<<应用vb4.0实现工业控制的实时曲线和历史曲线>>( http://www.swm.com.cn/yingyong/rj-98-yy4/98-y4-yy6.htm).
以上只是实时曲线绘制的一点简单说明,具体应用中可能需要花更多的功夫修饰图像,显示时间(可以依据上面的代码中的picture1.print实现),但是基本原理大同小异.