none
vb 2005 picturebox绘图 RRS feed

  • 問題

  • 这段代码主要是实现将从串口接收过来的数据在picturebox中画出曲线

    并且每画完一个屏幕以后就自动保存图像;当然后期还有许多功能要做。

    画曲线的代码在timer的tick事件中实现:

    Public Class Form1
        Dim i As Integer = 0
        Dim DataPointf(1000) As PointF
        Dim bmp As Bitmap
        Dim grr As Graphics
        Dim filename As String

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            bmp = New Bitmap(PicBOX1.Width, PicBOX1.Height)     
            grr = Graphics.FromImage(bmp)
            grr.Clear(PicBOX1.BackColor)


            Timer1.Interval = 100
            Timer1.Enabled = True
     
        End Sub
        Private Sub Drawset()
           
            grr.DrawLine(Pens.Black, 44, 280, 524, 280)    'draw x-axis

            grr.DrawLine(Pens.Black, 44, 280, 44, 0)            'draw Temperature-axis

            grr.DrawLine(Pens.Black, 524, 280, 524, 0)            'draw Pressure-axis

            Dim i As Integer = 0
            Do
                grr.DrawLine(Pens.Black, i * 60 + 104, 275, i * 60 + 104, 285)    ' draw x-axis tick mark
                i = i + 1
            Loop While i < 7

            Dim j As Integer = 0
            Do
                grr.DrawLine(Pens.Black, 40, j * 28, 48, j * 28)            ' draw deeee-axis tick mark
                j = j + 1
            Loop While j < 10

            Dim k As Integer = 0
            Do
                grr.DrawLine(Pens.Black, 520, k * 28, 528, k * 28)      ' draw EEV opening tick mark
                k = k + 1
            Loop While k < 10


            grr.DrawString("50℃", Me.Font, Brushes.Black, 10, 0)
            grr.DrawString("40℃", Me.Font, Brushes.Black, 10, 18 + 28 + 5)
            grr.DrawString("30℃", Me.Font, Brushes.Black, 10, 18 + 28 * 3 + 5)
            grr.DrawString("20℃", Me.Font, Brushes.Black, 10, 18 + 28 * 5 + 5)
            grr.DrawString("10℃", Me.Font, Brushes.Black, 10, 18 + 28 * 7 + 5)
            grr.DrawString("0", Me.Font, Brushes.Black, 20, 18 + 28 * 9 + 5)

            grr.DrawString("3", Me.Font, Brushes.Black, 104, 295)
            grr.DrawString("6", Me.Font, Brushes.Black, 104 + 60 * 1, 295)
            grr.DrawString("9", Me.Font, Brushes.Black, 104 + 60 * 2, 295)
            grr.DrawString("12", Me.Font, Brushes.Black, 104 + 60 * 3, 295)
            grr.DrawString("15", Me.Font, Brushes.Black, 104 + 60 * 4, 295)
            grr.DrawString("18", Me.Font, Brushes.Black, 104 + 60 * 5, 295)
            grr.DrawString("21", Me.Font, Brushes.Black, 104 + 60 * 6, 295)
            grr.DrawString("24", Me.Font, Brushes.Black, 104 + 60 * 7, 295)


            grr.DrawString("2.5 Mpa", Me.Font, Brushes.Black, 530, 0)
            grr.DrawString("2.25 MPa", Me.Font, Brushes.Black, 530, 18 + 5)
            grr.DrawString("2 MPa", Me.Font, Brushes.Black, 530, 18 + 28 + 5)
            grr.DrawString("1.75 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 2 + 5)
            grr.DrawString("1.5 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 3 + 5)
            grr.DrawString("1.25 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 4 + 5)
            grr.DrawString("1 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 5 + 5)
            grr.DrawString("0.75 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 6 + 5)
            grr.DrawString("0.5 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 7 + 5)
            grr.DrawString("0.25 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 8 + 5)
            grr.DrawString("0", Me.Font, Brushes.Black, 530, 18 + 28 * 9 + 5)
        End Sub

     
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Timer1.Enabled = False
            grr.DrawLine(Pens.Blue, i + 80, 30, i + 81, 30)
            PicBOX1.Image = bmp

            ReDim Preserve DataPointf(i)
            DataPointf(i).X = i + 80
            DataPointf(i).Y = 30

            i += 1
            filename = Convert.ToString(Now)
            filename = Replace(filename, ":", "_")

            If i > 300 Then
                i = 0
                Call Drawset()
                bmp.Save("E:\" & filename & ".bmp", System.Drawing.Imaging.ImageFormat.Bmp)
                PicBOX1.Refresh()

            End If
            Timer1.Enabled = True

        End Sub

        Private Sub PicBOX_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PicBOX1.Paint
         
            e.Graphics.Clear(PicBOX1.BackColor)               
            e.Graphics.DrawLine(Pens.Black, 44, 280, 524, 280)    'draw x-axis

            e.Graphics.DrawLine(Pens.Black, 44, 280, 44, 0)            'draw Temperature-axis

            e.Graphics.DrawLine(Pens.Black, 524, 280, 524, 0)            'draw Pressure-axis

            Dim n As Integer = 0
            Do
                e.Graphics.DrawLine(Pens.Black, n * 60 + 104, 275, n * 60 + 104, 285)    ' draw x-axis tick mark
                n = n + 1
            Loop While n < 7

            Dim j As Integer = 0
            Do
                e.Graphics.DrawLine(Pens.Black, 40, j * 28, 48, j * 28)            ' draw deeee-axis tick mark
                j = j + 1
            Loop While j < 10

            Dim k As Integer = 0
            Do
                e.Graphics.DrawLine(Pens.Black, 520, k * 28, 528, k * 28)      ' draw EEV opening tick mark
                k = k + 1
            Loop While k < 10


            e.Graphics.DrawString("50℃", Me.Font, Brushes.Black, 10, 0)
            e.Graphics.DrawString("40℃", Me.Font, Brushes.Black, 10, 18 + 28 + 5)
            e.Graphics.DrawString("30℃", Me.Font, Brushes.Black, 10, 18 + 28 * 3 + 5)
            e.Graphics.DrawString("20℃", Me.Font, Brushes.Black, 10, 18 + 28 * 5 + 5)
            e.Graphics.DrawString("10℃", Me.Font, Brushes.Black, 10, 18 + 28 * 7 + 5)
            e.Graphics.DrawString("0", Me.Font, Brushes.Black, 20, 18 + 28 * 9 + 5)

            e.Graphics.DrawString("3", Me.Font, Brushes.Black, 104, 295)
            e.Graphics.DrawString("6", Me.Font, Brushes.Black, 104 + 60 * 1, 295)
            e.Graphics.DrawString("9", Me.Font, Brushes.Black, 104 + 60 * 2, 295)
            e.Graphics.DrawString("12", Me.Font, Brushes.Black, 104 + 60 * 3, 295)
            e.Graphics.DrawString("15", Me.Font, Brushes.Black, 104 + 60 * 4, 295)
            e.Graphics.DrawString("18", Me.Font, Brushes.Black, 104 + 60 * 5, 295)
            e.Graphics.DrawString("21", Me.Font, Brushes.Black, 104 + 60 * 6, 295)
            e.Graphics.DrawString("24", Me.Font, Brushes.Black, 104 + 60 * 7, 295)


            e.Graphics.DrawString("2.5 Mpa", Me.Font, Brushes.Black, 530, 0)
            e.Graphics.DrawString("2.25 MPa", Me.Font, Brushes.Black, 530, 18 + 5)
            e.Graphics.DrawString("2 MPa", Me.Font, Brushes.Black, 530, 18 + 28 + 5)
            e.Graphics.DrawString("1.75 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 2 + 5)
            e.Graphics.DrawString("1.5 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 3 + 5)
            e.Graphics.DrawString("1.25 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 4 + 5)
            e.Graphics.DrawString("1 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 5 + 5)
            e.Graphics.DrawString("0.75 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 6 + 5)
            e.Graphics.DrawString("0.5 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 7 + 5)
            e.Graphics.DrawString("0.25 MPa", Me.Font, Brushes.Black, 530, 18 + 28 * 8 + 5)
            e.Graphics.DrawString("0", Me.Font, Brushes.Black, 530, 18 + 28 * 9 + 5)
             
            e.Graphics.DrawLines(Pens.Blue, DataPointf)
            e.Dispose()
        End Sub
    End Class

    现在的问题是,单步运行的时候程序不会报错,但是全速运行时会出现错误

    错误出现在e.Graphics.DrawLines(Pens.Blue, DataPointf)这一句

    错误是:parameter is not valid.而且此刻datapointf数组里面只有一个

    元素(80,30),问题就在这儿。

    但是我不明白,为什么这个数组里面会只有一个元素而报错呢;

    当我把重绘语句改成

    Dim m As Integer
    For m = 0 To i
    e.Graphics.DrawLine(Pens.Blue, m + 80, 30, m + 81, 30)
    Next

    一切运行正常,我不明白前面的那种方法为什么不可以;

    请各位前辈赐教!

    谢谢
    2009年3月17日 上午 02:28

解答

  • HI,

    DataPointF陣列中必須至少有兩點, 才能繪一直線, 您的狀況應該是在某個時間點, DataPointF陣列中只有一點, 而發生錯誤
    2009年3月17日 上午 04:28
  •  ReDim Preserve DataPointf(i)

    上列會把陣列重新宣告為i的大小,您宣告i初始值為0,paint事件觸發時,這時陣列只有1個;而單步執行時,Timer已產生好幾個陣列了...
    • 已編輯 Joe Hung 2009年3月17日 下午 01:00
    • 已標示為解答 璉璉Moderator 2009年3月21日 上午 04:00
    2009年3月17日 上午 08:54

所有回覆

  • HI,

    DataPointF陣列中必須至少有兩點, 才能繪一直線, 您的狀況應該是在某個時間點, DataPointF陣列中只有一點, 而發生錯誤
    2009年3月17日 上午 04:28
  • 什么情况下会出现只有一个点呢?

    关键是全速运行一开始就会有error出现

    2009年3月17日 上午 05:21
  •  版大,能幫我看看嗎

    我知道是因為datapointf陣列里隻有一個元素

    但是為什么會出現這種情況呢?

    單步運行是不會有error的

    另外我的這種情況采用這種方式畫圖是否閤適啊?

    謝謝
    2009年3月17日 上午 07:12
  •          If UBound(DataPointf) > 0 Then
                e.Graphics.DrawLines(Pens.Blue, DataPointf)
            End If

    一開始時,陣列只有一個,就會造成例外,改成以上,應該就可以了吧?!
    2009年3月17日 上午 07:53
  • 問題解決了

    謝謝前輩

    可是為什么?

    我預先已經定義了Dim DataPointf(1000) As PointF

    盡管沒有賦值,可是單步運行的時候可以看到陣列中

    缺省賦值都是(0,0);

    为什么会在程序中会突然陣列只有一个值?

    这种情况是怎么产生的?




















    2009年3月17日 上午 08:16
  • 而且这个值是(80,30),

    很顯然是執行到tick事件中

    ReDim Preserve DataPointf(i)
            DataPointf(i).X = i + 80
            DataPointf(i).Y = 30

    上麵的代碼后才産生的錯誤?

    難道這個時候paint事件會被觸髮?

    謝謝
    2009年3月17日 上午 08:20
  •  ReDim Preserve DataPointf(i)

    上列會把陣列重新宣告為i的大小,您宣告i初始值為0,paint事件觸發時,這時陣列只有1個;而單步執行時,Timer已產生好幾個陣列了...
    • 已編輯 Joe Hung 2009年3月17日 下午 01:00
    • 已標示為解答 璉璉Moderator 2009年3月21日 上午 04:00
    2009年3月17日 上午 08:54
  •  土土的問

    難道不是先執行paint事件

    然后執行timer的tick事件嗎?
    2009年3月17日 上午 10:03
  •          PicBOX1.Image = bmp

    在下前面寫錯了,上列會觸發paint 事件,執行完Timer的tick事件,才會執行paint,第一次時,陣列只有一個,就會造成錯誤...
    2009年3月17日 下午 01:04
  • 非常非常感谢!

    bow
    2009年3月18日 上午 02:08
  • paint 事件是在螢幕發生重繪時,強制發生應加在 Form_Load / Form_Active 等事件
    Timer 事件是依 Tick 密度發生

    當 Form_Load -> Tick 較短,且尚未 Form.Show 時
    就有可能先發生 Timer 事件
    T.L. Cheng
    2009年3月21日 上午 04:03
    版主