aus einem Programm heraus möchte ich Messdaten in einem zweiten (zuschaltbaren) Fenster graphisch darstellen.
Um die Grundlagen zu verstehen und zu optimieren, habe ich ein kleines Hilfsprogramm "polygraf" erstellt.
In dem Programm wird ein Polynom 3. Grades berechnet und die Werte werden in ListBox1 ausgegeben und in Form2Chart1 dargestellt.
Die Faktoren a0 - a3, der Wertebereich xmin, xmax werden mit FloatSpinEdit und die Auflösung (Anzahl der Koordinatenpaare) mit SpinEdit eingestellt.
Dies funktioniert soweit auch vernünftig.
Hier der Quelltext Form1:
Code: Alles auswählen
unit polygrafu1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
Buttons, Spin;
type
{ TForm1 }
TForm1 = class(TForm)
BitBtn1: TBitBtn;
btBerechne: TButton;
btGrafik: TButton;
FloatSpinEdit1: TFloatSpinEdit;
FloatSpinEdit2: TFloatSpinEdit;
FloatSpinEdit3: TFloatSpinEdit;
FloatSpinEdit4: TFloatSpinEdit;
FloatSpinEdit5: TFloatSpinEdit;
FloatSpinEdit6: TFloatSpinEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
ListBox1: TListBox;
SpinEdit1: TSpinEdit;
procedure btBerechneClick(Sender: TObject);
procedure btGrafikClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
uses polygrafu2;
type TFeld = record
x,y :single;
end;
var blGrafik :boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption:='a3';
Label2.Caption:='a2';
Label3.Caption:='a1';
Label4.Caption:='a0';
Label5.Caption:='xmin';
Label6.Caption:='xmax';
Label7.Caption:='Auflös.';
FloatSpinEdit1.Value:=0;
FloatSpinEdit2.Value:=1;
FloatSpinEdit3.Value:=0;
FloatSpinEdit4.Value:=0;
FloatSpinEdit5.Value:=-3;
FloatSpinEdit6.Value:=3;
SpinEdit1.Increment:=10;
SpinEdit1.MaxValue:=1000;
SpinEdit1.MinValue:=1;
SpinEdit1.Value:=100;
blGrafik:=false;
btGrafik.Caption:='Grafik an';
end; {FormCreate}
procedure TForm1.btBerechneClick(Sender: TObject);
var a,i :integer;
sw,a3,a2,a1,a0,x,y,xmin,xmax :single;
feld :array of TFeld;
begin
Screen.Cursor:=crHourGlass;
ListBox1.Clear;
Form2.Chart1LineSeries1.Clear; <-- hier ist wahrscheinlich die Problemzeile
a3:=FloatSpinEdit1.Value;
a2:=FloatSpinEdit2.Value;
a1:=FloatSpinEdit3.Value;
a0:=FloatSpinEdit4.Value;
xmin:=FloatSpinEdit5.Value;
xmax:=FloatSpinEdit6.Value;
a:=SpinEdit1.Value;
sw:=(xmax-xmin)/a;
x:=xmin;
SetLength(feld,a+1);
i:=0;
while x<xmax+sw do begin
y:=a3*x*x*x+a2*x*x+a1*x+a0;
feld[i].x:=x;
feld[i].y:=y;
x:=x+sw;
inc(i);
end; {while}
for i:=Low(feld) to High(feld) do begin ListBox1.Items.Add
(FloatToStrF(feld[i].x,ffFixed,4,2)+' '+FloatToStrF(feld[i].y,ffFixed,4,2));
Form2.Chart1LineSeries1.AddXY(feld[i].x,feld[i].y);
end; {for}
// Form2.Chart1.AddSeries(LS1);
SetLength(feld,0);
Screen.Cursor:=crDefault;
end; {btBerechne}
procedure TForm1.btGrafikClick(Sender: TObject);
begin
blGrafik:=not blGrafik;
if blGrafik then begin
btGrafik.Caption:='Grafik aus';
Form2.Visible:=true;
end else begin
btGrafik.Caption:='Grafik an';
Form2.Visible:=false;
Form2.Chart1.Refresh;
end;
end; {btGrafikClick}
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
Form2.Close;
end; {FormClose}
end.
und Form2:
Code: Alles auswählen
unit polygrafu2;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, TAGraph,
TASeries;
type
{ TForm2 }
TForm2 = class(TForm)
Chart1: TChart;
Chart1LineSeries1: TLineSeries;
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.lfm}
{ TForm2 }
procedure TForm2.FormCreate(Sender: TObject);
begin
// Chart1LineSeries1:=TLineSeries.Create(self);
Chart1LineSeries1.ShowLines:=true;
Chart1LineSeries1.LinePen.Color:=clBlue;
Chart1LineSeries1.ShowPoints:=false;
// Chart1LineSeries1.Pointer.Style:=psCircle;
Chart1LineSeries1.Pointer.Brush.Color:=clBlue;
Chart1.AddSeries(Chart1LineSeries1);
Chart1.Proportional:=false;
end;
end.
Zuvor werden die Werte mit "SetLength(feld,0)" bzw. "Form2.Chart1LineSeries1.Clear;" zurückgesetzt.
Die Schrittweite sw wird bestimmt durch "sw:=(xmax-xmin)/a;"). Fange ich mit einer Auflösung von a=100 an,
so stürzt das Programm nach der zweiten Berechnung mit der Fehlermeldung:
Code: Alles auswählen
Projekt polygraf.exe hat Exception-Klasse >>External SIGSEGV<< ausgelöst
Code: Alles auswählen
procedure von control.inc
Code: Alles auswählen
procedure TControl.Click;
begin
//DebugLn(['TControl.Click ',DbgSName(Self)]);
if (not (csDesigning in ComponentState)) and (ActionLink <> nil) and
((Action=nil) or (@FOnClick <> @Action.OnExecute) or Assigned(FOnClick)) then
ActionLink.Execute(Self)
else
if Assigned(FOnClick) then
FOnClick(Self); <-- der Cursor springt nach Fehlermeldung hier her
end;
Mit dem Debugger habe ich die Stelle in Form1, die zum Absturz führt, mit
Code: Alles auswählen
Form2.Chart1LineSeries1.Clear;
Wer hat eine Ahnung wo das Problem liegen könnte?
Ich hänge zwei Bilder von Form1 und Form2, sowie den Projektordner an. Vielleicht hat jemand Zeit, um das Problem nach zuvollziehen.
Vielen Dank.
Gruß, Linkat
Ich habe das Ganze mit Lazarus 0.9.30 vom März 2011 entwickelt. Aus Verzweiflung habe ich heute die Version 0.30.1 mit FPC 2.4.4 installiert. Leider hat sich an dem Problem nichts geändert.