前言
这是基于我之前的一篇博文:
使用visual Studio 2019在VB.net中新添自定义画图函数
在此基础上,我优化了一下,改进了UI,添加了示例功能,即以画圆函数为基础,添加了走马灯功能。
先看一下最终效果:
1、UI布置
首先大致布局一下窗体控件:
VB.net的窗体布局很简单,当然同时效果也就那样,如果要UI美观,需要自己设计一下,包括配色以及图片。
但本文不涉及UI美化,可能会在以后单独介绍。
2、画圆函数
''' <summary>
''' 在PictureBox中画一个圆
''' </summary>
''' <param name="p"></param>
''' <param name="c"></param>
Private Sub huayuan(p As PictureBox, c As Color)
Dim b As Bitmap = New Bitmap(p.Width, p.Height)
Dim g As Graphics = Graphics.FromImage(b)
Dim mybrush As New SolidBrush(c)
g.FillEllipse(mybrush, 0, 0, p.Width, p.Height)
g.Dispose()
p.Image = b
End Sub
画圆函数还是和之前一样,稍微解释下:
自定义的huayuan函数,有两个参数,一个是PictureBox实例,一个是颜色。
函数内,使用bitmap绘制圆形并填充色块,即我们所需的圆形,然后将bitmap作为image赋予PictureBox的图片属性。
这样我们就在图片框中画了一个圆形。
3、走马灯
如上图,我们一共添加了8个PictureBox,用于实现走马灯,即8个图片框按顺序点亮(由灰色变为红色)。实现这个功能有多种方式,本文选择的是利用定时器来实现。
所以,我们需要在窗体添加一个Timer控件。
在VB.net中,Timer控件是系统工具箱自带的,可以直接拖到窗体上。
Timer的使用也很简单,设置一下其定时间隔:
Timer1.Interval = NumericUpDown1.Value
本文中,Timer的间隔可以自定义设置,单位为毫秒。
Timer设置了时间间隔后,直接调用start,定时器就启动了,每间隔一次,就会触发Tick事件,我们可以在这个Tick事件里去编写我们的逻辑,本文中,就是利用画圆函数给PictureBox轮流画圆。
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
x += 1
'Console.WriteLine(x)
If x <= 8 And flag Then
Button1.Enabled = False
Move_led(x, 1)
Else
Button1.Enabled = True
Button2.Enabled = False
Button3.Enabled = False
x = 0
Label12.Text = 0
Label14.Text = "停止中"
'走马灯完成后,恢复初始状态
init_led()
Timer1.Stop()
flag = False
End If
End Sub
其中调用的Move_led函数如下:
''' <summary>
''' 走马灯程序
''' 为了防止循环阻塞主线程,可以添加异步方式
''' </summary>
Private Sub Move_led(count As Integer, timedelay As Integer)
Label12.Text = count.ToString()
For j As Integer = 1 To 8 Step 1
Dim str11 = "x" & count.ToString() + "j" & j.ToString()
'Console.WriteLine(str11)
Dim pic1 As PictureBox = Me.Controls("PictureBox" & j)
'Console.WriteLine(pic1.Name)
If j = count Then
huayuan(pic1, Color.Red)
Else
huayuan(pic1, Color.Gray)
End If
'添加异步等待时间
'Await Task.Delay(1)
Next
'添加异步等待时间
'Await Task.Delay(timedelay)
End Sub
这里的大致逻辑就是,设置一个计数,在定时器的Tick事件里,每次都判断计数的大小,如果小于8,就根据计数值执行画圆函数,当然此处又有一个判断函数Move_led,用于对8个图片框分别画圆。执行完后,对计数值加1,然后等待下次定时器触发再判断,直到计数值大于8,也就是走马灯结束,那么就恢复初始值。
以下是完整代码:
控件说明:
Form:1,
Button:3,
Label:14,
PictureBox:8,
NumericUpDown:1
Imports System.Threading.Thread
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Text = "走马灯演示"
Me.Size = New Size(600, 400)
Me.Location = New Point(100, 40)
NumericUpDown1.Value = 100
'最长间隔100000ms=100s
NumericUpDown1.Maximum = 100000
'最短间隔10ms=0.01s
NumericUpDown1.Minimum = 10
Timer1.Interval = 100
Label12.Text = 0
Label14.Text = "无"
Button2.Enabled = False
Button3.Enabled = False
init_led()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Interval = NumericUpDown1.Value
Timer1.Start()
flag = True
Label14.Text = "运行中"
Button1.Enabled = False
Button2.Enabled = True
Button3.Enabled = False
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Timer1.Stop()
flag = False
Button1.Enabled = True
Label14.Text = "停止中"
Button1.Enabled = True
Button2.Enabled = False
Button3.Enabled = True
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Stop()
flag = False
x = 0
Label14.Text = "无"
Label12.Text = 0
Button1.Enabled = True
Button2.Enabled = False
Button3.Enabled = False
For i As Integer = 1 To 8 Step 1
Dim pic1 = Me.Controls("PictureBox" & i)
huayuan(pic1, Color.Gray)
Next
End Sub
Dim x As Integer = 0
Dim flag As Boolean = False
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
x += 1
'Console.WriteLine(x)
If x <= 8 And flag Then
Button1.Enabled = False
Move_led(x, 1)
Else
Button1.Enabled = True
Button2.Enabled = False
Button3.Enabled = False
x = 0
Label12.Text = 0
Label14.Text = "停止中"
'走马灯完成后,恢复初始状态
init_led()
Timer1.Stop()
flag = False
End If
End Sub
''' <summary>
''' 初始化参数
''' </summary>
Private Sub init_led()
'统一为Label赋值
For i As Integer = 1 To 8 Step 1
Me.Controls("Label" & i).Text = "灯" & i
Dim pic1 = Me.Controls("PictureBox" & i)
huayuan(pic1, Color.Gray)
Console.WriteLine(pic1.Name)
Next
End Sub
''' <summary>
''' 走马灯程序
''' 为了防止循环阻塞主线程,可以添加异步方式
''' </summary>
Private Sub Move_led(count As Integer, timedelay As Integer)
Label12.Text = count.ToString()
For j As Integer = 1 To 8 Step 1
Dim str11 = "x" & count.ToString() + "j" & j.ToString()
'Console.WriteLine(str11)
Dim pic1 As PictureBox = Me.Controls("PictureBox" & j)
'Console.WriteLine(pic1.Name)
If j = count Then
huayuan(pic1, Color.Red)
Else
huayuan(pic1, Color.Gray)
End If
'添加异步等待时间
'Await Task.Delay(1)
Next
'添加异步等待时间
'Await Task.Delay(timedelay)
End Sub
''' <summary>
''' 在PictureBox中画一个圆
''' </summary>
''' <param name="p"></param>
''' <param name="c"></param>
Private Sub huayuan(p As PictureBox, c As Color)
Dim b As Bitmap = New Bitmap(p.Width, p.Height)
Dim g As Graphics = Graphics.FromImage(b)
Dim mybrush As New SolidBrush(c)
g.FillEllipse(mybrush, 0, 0, p.Width, p.Height)
g.Dispose()
p.Image = b
End Sub
End Class
注:事实上本文虽然介绍的是画圆,但可以扩展到任意图形的绘制,只需要对huayuan函数作一些修改即可。我在之前的那篇文章里也说过,本文实际是用于工控行业的上位机编写的一部分,单独列出来,一是方便,作个记录,以便于后来查看,二是如果有这方面需求的朋友,假如能够帮助到你,那么也是非常好的。