简单介绍

自学的delphi,根据老师布置的任务,打磨了三天吧,蛮辛苦的。
但是还有很多困惑。 前几天的也写了一个自我感觉不是很好花了一天 重新写了一下 ,原来的直接把画图 和读取数据 直接写在 按钮的响应时间下面的 ;这次我把他们整合在三个函数里面了,本来想用 oop思想去写的但没有学完delphi,没有实现 ;其实我还有困惑的 比如说我想窗口创立的完成的时候 就把坐标图画好,然后我写到了 oncreate 事件下面 但是并没有 和我想的一样 ,然后 我又想放到onpaint 事件下 但是 每次画曲线的时候 就会触发这个时间 又给我覆盖过去了 甚是头疼 ,这个应该可以和 sdk编程一样可以 发送一个 paint消息调用 绘图函数吧 ,其实 我sdk 也是是个了解 ,感觉自己要学得东西蛮多的。

美妹

作业

image.png

代码

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls, Vcl.ExtCtrls,
  InData,Vcl.ComCtrls;

type
  TForm1 = class(TForm)
    pnl1: TPanel;
    pnl2: TPanel;
    btnInData: TButton;
    strngrdData: TStringGrid;
    pbPaint: TPaintBox;
    btnPaint1: TButton;
    grpNum: TGroupBox;
    edtNum: TEdit;
    udNum: TUpDown;
    lblNum: TLabel;
    btnpaint2: TButton;
    btnpaintall: TButton;
    procedure FormActivate(Sender: TObject);
    procedure btnInDataClick(Sender: TObject);
    procedure btnPaint1Click(Sender: TObject);
    procedure btnpaint2Click(Sender: TObject);
    procedure btnpaintallClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  var n1,n2:Integer;//n1,n2保存着文件的行数
  var Data1,Data2 : ArrayData;//Arraydata 是专门用来存着本次数据的数组

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);//初始化一些巴拉巴拉
begin
    strngrdData.Cells[0,0]:='数据1' ;
    strngrdData.Cells[3,0]:='数据2' ;
    strngrdData.ColCount:=5;
    n1:=0;
    n2:=0;
end;




procedure TForm1.btnInDataClick(Sender: TObject);
var i:Integer;
begin
  //读取数据
  n1:=GetData(Data1,'Data1.txt');
  n2:=GetData(Data2,'Data2.txt');
  i:=0;
  //把数据输入打到表格里
  for I := 0 to n1 do
  begin
    strngrdData.Cells[0,i+1]:=FloatToStr(data1[0,i]);
    strngrdData.Cells[1,i+1]:=FloatToStr(data1[1,i]);
  end;
  for I := 0 to n2 do
  begin
    strngrdData.Cells[3,i+1]:=FloatToStr(data2[0,i]);
    strngrdData.Cells[4,i+1]:=FloatToStr(data2[1,i]);
  end;
  //调一下行数
  if n1>n2 then
  strngrdData.RowCount:=n1
  else
  strngrdData.RowCount:=n2;
end;

procedure TForm1.btnPaint1Click(Sender: TObject);
begin
 Paintbk (pbpaint); //要覆盖掉 原先的东西
 PaintData (pbpaint,Data1,n1,clred);
end;


procedure TForm1.btnpaint2Click(Sender: TObject);
begin
Paintbk (pbpaint);
 PaintData (pbpaint,Data2,n2,clGreen);
end;

procedure TForm1.btnpaintallClick(Sender: TObject);
begin
Paintbk (pbpaint);
 PaintData (pbpaint,Data2,n2,clGreen);
 PaintData (pbpaint,Data1,n1,clred);

end;

end.

引用的Indata单元

unit InData;


interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls, Vcl.ExtCtrls,
  Vcl.ComCtrls;


type ArrayData= array[0..1] of array[0..600] of Real;// 0 存的是x数据,1存的是y数据
Function  GetData(var p:ArrayData;const S:string):Integer; //从文件里读出数据并且返回这个文件的行数
procedure Paintbk (pbpaint:TPaintBox);//绘制坐标图
procedure PaintData (pbpaint:TPaintBox;p:Arraydata;n:Integer;C:TColor);//绘制曲线

implementation

Function  GetData(var p:ArrayData;const S:string):Integer;
var
    File1:Textfile;
    i:Integer;
begin
  i:=0;
  AssignFile(File1,s);
  Reset(File1); //读取文件
  try
      while not Eof(File1) do begin
        Readln(File1,p[0,i],p[1,i]);
        i:=i+1;
      end;
  finally
       CloseFile(file1);
  end;
  Result:=i;
end;
procedure Paintbk (pbpaint:TPaintBox);
var
i,W,H:Integer;
r:Real;//用来储存单位值
begin
W:=pbpaint.Width;
H:=pbpaint.Height;
//绘制一下坐标系
    with pbPaint.Canvas do begin
    Brush.Color:=RGB(250,250,210);
    FillRect(Rect(0,0,W,H));
    Pen.Color:=clBlue;
    pen.Width:=2;
    MoveTo(15,H-15);
    LineTo(W,H-15);
    MoveTo(15,0);
    LineTo(15,H-15);
    Font.Size:=6;
    TextOut(W-100,H-30,'X轴');
    TextOut(20,H div 2,'Y');
    TextOut(20,H div 2 + 15,'轴');
    TextOut(5,H-15,'(0,0)');
    end;
//绘制网格
    pbPaint.Canvas.Pen.color:=RGB(220,220,220);
    pbPaint.Canvas.pen.Width:=1;
    pbPaint.Canvas.Font.Size:=6;
    i:=15;     //纵轴
      while i<=W   do begin

          with pbPaint.Canvas do begin
            Inc(i,10);
             MoveTo(i,0);
             LineTo(i,H-15);
             r:= I*90/w; //打印上去 那个的对应的坐标数值
             TextOut(i,pbPaint.Height-15,intToStr(round(r)));
          end;
       end;
    I:=H-15;    //横轴
    pbPaint.Canvas.Font.Size:=4;
      while i>15  do begin

          with pbPaint.Canvas do begin
            Dec(i,10);
            MOveTo(15,i);
            LineTo(pbPaint.Width,i);
            r:= I*1500/h;
            TextOut(10,pbPaint.Height-i,intToStr(round(r)));
          end;
       end;
end;
procedure PaintData (pbpaint:TPaintBox;p:Arraydata;n:Integer;C:TColor);
var
i,W,H:Integer;
x,y:array[0..600] of Integer;//由于坐标是整数,所以要类型转换
begin
W:=pbpaint.Width-15;
H:=pbpaint.Height-15;
  for I := 0 to n do  //进行坐标转换
  begin
    x[i]:=Round(p[0,i]*(w/90))+15;
    y[i]:=H-Round(p[1,i]*H/1500);
  end;

  {
  按比例缩放 x数据最大值大概在90左右
  y的最大值在   1500左右 那么就 每个数值缩放
  最大宽度/最大数值 然后 就可以完整的在这里面地显示了
   也就是 每个像素 表示  最大数值/最大像素
  }
//绘制曲线
  pbPaint.Canvas.Pen.color:=C;
  pbPaint.Canvas.MoveTo(15,H);
  for I := 0 to n-1 do
  begin
    with pbPaint.Canvas do
    begin
      LineTo(x[i],y[i]);
    end;
  end;
end;
end.

大功告成

image.png

努力成长的程序员