十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
分类: 电脑/网络 程序设计 其他编程语言
创新互联建站主营沁阳网站建设的网络公司,主营网站建设方案,APP应用开发,沁阳h5成都微信小程序搭建,沁阳网站营销推广欢迎沁阳等地区企业咨询
问题描述:
如何用VB做一个程序可以用鼠标画曲线,
解析:
在工控制软件中,实时曲线的绘制用途非常的广泛,它可以很直观的显示腊腔者出监控数据的变化值和变化趋势。在VB中实现曲线的绘制有很多种方法,本文介绍一种非常简单的方法来实现实时曲轮薯线的绘制。
在VB中实现实时曲线的绘制,要利用VB的PictureBox(图像)控件,和画线函数line(x1,y1)-(x2,y2)。PictureBox控件,可以作为一个“容器”,在它的里面可以包含很多的对象。也可以执行很多VB的内部函数。
要实现实时曲线的绘制,肯定要有外部实时数据的输入,这里假设是有一个数据从计算机的串口输入 定义该数据变量为DataFromCom。实时曲线反映的就是该数据。
打开VB6.0中文版,新建一个项目和窗体,修改窗体的属性,将“Heigh”修改为:8000,“Width”修改为在窗体中放如一个PictureBox控件。然后重新定义PictureBox控件的一些基本属性,在VB中选中PictureBox控件,直接在它的属性框中,修改一些属性参数。“名称”改为Pic。 “AutoRedraw”改为:True。“BackColor”改为:H***********(墨绿色背景颜色)。”Heigh”改为:5000。“Width”改为:8000。如图1所示:
然后要重新定义PictureBox控件的坐标系。图像框的默认坐标系,是从左上角开始的,不符合我们的画线要求。修改坐标系的目的是让曲线从图像框的左边正中间,开始画线。修改图像框的坐标系,这里定义一个过程PicScale(),代码如下:
Private Sub PicScale(picX As PictureBox)
picX.Scale (0, PicX.ScaleHeight)-(picX.ScaleWidth, -PicX.ScaleHeight)
End Sub
一般的实时曲线显示的时候在屏幕的正中间有一条基准线,这圆毁里也要画出这条基准线,用一个过程PicMidleLine()来实现,代码如下:
Private Sub PicMidleLine( picX As PictureBox)
picX.Line (0, 0)-(picX.ScaleWidth, 0), vbGreen '画出中线
End Sub
要画一条实时曲线,坐标轴的设定很重要,在这里把X轴设定为时间轴,Y轴设定为数据轴。对应X轴我们定义一个时间变量TimeCount,TimeCount会随着时间逐渐递增,每次递增,对应着一个从串口读过来的数据DataFromCom,这样图像框中的(x,y)坐标点实际上就对应着(TimeCount,DataFromCom)如果只是当TimeCount发生变化时就在图像框上画一个点,就只需调用VB中的画像素的函数point(x,y),这里x,y为所画的点的坐标。单这样画出来的是一个个不连续的点。我们想要的是实时的连续的曲线,所以要调用VB中的画线的函数line(x1,y1)-(x2,y2),这里(x1,y1)(x2,y2)为所要画的线的起点和终点的坐标。只要把上次串口读过来的数据(这里把它定义为变量DataFromComLast)和现在串口读过来的数据(DataFromCom)和TimeCount相对应,调用line(x1,y1)-(x2,y2)函数就可以在图像框中画出实时的曲线了。把它写成一个过程如下面的代码:
Private Sub DrawRealLine(picX As PictureBox, TimeCountX As Integer, DataFromComX As Integer, DataFromComLastX As Integer)
If TimeCountX - 1 0 Then
picX.Line (TimeCountX - 1, DataFromComLastX)-(TimeCountX, DataFromComX), vbWhite
End If
End Sub
有了三个过程就可以在图像框中画出一条实时的曲线了。
DrawRealLine()过程中的picX.Line (TimeCountX - 1, DataFromComLastX)-(TimeCountX, DataFromComX), vbWhite所画线的起始点和结束点都是以像素为单位的,这样以来如果不改变的话,画出来的线将是一个屏幕上像素相连的很密的曲线,通过调整line(x1,y1)-(x2,y2)
中的x的值,就可以画出分布密度不一样的曲线,这里为了在屏幕上能够看到不是很密的曲线我们把x乘以一个系数10,修改为:
picX.Line ((TimeCountX - 1) * 10, DataFromComLastX)-(TimeCountX * 10, DataFromComX), vbWhite
这比较容易在屏幕上看到稀疏的曲线。
由于是仅仅讲解如何画出实时的曲线,读者的计算机上未必有和串口相连的设备,这里用一个定时器控件来模拟从串口读过来的数据。在窗体上放入一个Timer控件,修改Timer控件的属性为:“Enable”该为True,“Interval”改为300。双击Timer控件在它的过程中,添加代码后如下:
Private Sub Timer1_Timer()
DataFromComLast = DataFromCom
Randomize
DataFromCom = 3000 * Rnd
TimeCount = TimeCount + 1
DrawRealLine Pic, TimeCount, DataFromCom, DataFromComLast
End Sub
这样在运行后就可以看到我们想要的实时曲线了,如下图:
图 2
下面是完整的代码:
Option Explicit
Dim DataFromCom As Integer '从串口读过来的实时值
Dim DataFromComLast As Integer '上次的串口值
Dim TimeCount As Integer
Private Sub Form_Load()
PicScale Pic '调整图像框的坐标系
PicMidleLine Pic '在图像框中画一条中线
End Sub
Private Sub PicScale(picX As PictureBox) '调整图像框的坐标系
picX.Scale (0, picX.ScaleHeight)-(picX.ScaleWidth, -picX.ScaleHeight)
End Sub
Private Sub PicMidleLine(picX As PictureBox) '在图像框中画一条中线
picX.Line (0, 0)-(picX.ScaleWidth, 0), vbGreen '画出中线
End Sub
Private Sub DrawRealLine(picX As PictureBox, TimeCountX As Integer, DataFromComX As Integer, DataFromComLastX As Integer)
If TimeCountX - 1 0 Then
picX.Line ((TimeCountX - 1) * 10, DataFromComLastX)-(TimeCountX * 10, DataFromComX), vbWhite
End If
End Sub
Private Sub Timer1_Timer()
DataFromComLast = DataFromCom
Randomize
DataFromCom = 3000 * Rnd
TimeCount = TimeCount + 1
DrawRealLine Pic, TimeCount, DataFromCom, DataFromComLast '画出实时的曲线
End Sub
在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" ‘保存图画,
您好,您是想问vb点虐 连续绘制曲线图不消物亩失怎么办?b点虐 连续绘制曲线图不消失的解决办法如下:
1、首先必须罩烂森创建bitmap,关联到picturebox1.image上。
2、再在历腔picturebox1.image上创建Graphics,再进行作图。即可显示线图。
拖一个PictureBox1控件 创建一个Paint事件。在事件中加入 Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint ' Create pens. Dim redPen As New Pen(Color.Red, 3) Dim greenPen As New Pen(Color.Green, 3) ' Create points that define curve. Dim point1 As New Point(50, 50) Dim point2 As New Point(100, 25) Dim point3 As New Point(200, 5) Dim point4 As New Point(250, 50) Dim point5 As New Point(300, 100) Dim point6 As New Point(350, 200) Dim point7 As New Point(250, 250) Dim curvePoints As Point() = {point1, point2, point3, point4, _ point5, point6, point7} ' Draw lines between original points to screen. e.Graphics.DrawLines(redPen, curvePoints) ' Draw curve to screen. e.Graphics.DrawCurve(greenPen, curvePoints) End Sub 得余册到数据后,改point的数据。漏颂然后返毁郑PictureBox1.Refresh()就行了