使用TPointSeries.Clear的奇怪行为

时间:2016-03-16 00:04:33

标签: delphi teechart delphi-6

(Delphi 6 with TChart,Win XP)

我试图从点系列中清除点数时出现了不稳定的行为,当然,这段代码曾经起作用。

基本上,我程序的这一部分会生成5个数据点并绘制它们。当我尝试使用OSC_Series.Clear清除它们时,我得到一个“List index out of bounds [0]”错误。

我检查确保我正在绘制的值没有什么奇怪的。一切都很好。然后我尝试了不同的东西来试图隔离并解决问题。

这是一些代码。

type
  TksGraph_DataFrm = class(TForm)
  .
  .
  .
  private
    OSC_Series: TPointSeries
  public
  end;

procedure TksGraph_DataFrm.cat7AnalysisInitialize(var P:TTest_Project);
begin

  // Do a bunch of stuff.

  // Set up the analysis data points series.
  OSC_Series:=TPointSeries.Create(self);
  AnalysisChart.AddSeries(OSC_Series);
  with OSC_Series do
  begin
    Title:='';
    HorizAxis:=aBothHorizAxis;
    VertAxis:=aBothVertAxis;
    SeriesColor:=clRed;
    Pointer.Brush.Color:=clYellow;
    Pointer.HorizSize:=4;
    Pointer.VertSize:=4;
    Pointer.Style:=psRectangle;
    Pointer.Visible:=true;
    LinePen.Color:=clBlack;
    LinePen.Width:=1;
    Linepen.Visible:=true;
    ShowInLegend:=false;
    XValues.Order:=LoNone;
  end;
end;

procedure TksGraph_DataFrm.cat7AnalysisRefresh(var P:TTest_Project);
var X,Y:single;
begin

  X:= some value
  Y:= some value

  // Plot the result.
  OSC_Series.AddXY(X,Y);
  showmessage(
    'Count = '+inttostr(OSC_Series.Count)+#13+
    'X = '+FloatToStr(X)+#13+
    'Y = '+FloatToStr(Y)+#13+
    'Plot-X = '+FloatToStr(OSC_Series.XValue[OSC_Series.Count-1])+#13+
    'Plot-Y = '+FloatToStr(OSC_Series.YValue[OSC_Series.Count-1]));

end;

这是我用来重置系列的例程。我包含的代码有效且无效。

procedure TksGraph_DataFrm.cat7AnalysisClear(var P:TTest_Project);
var i:integer;
begin

  // This should work, but it gives me the list out of bounds error
  // unless the count is 0.
  OSC_Series.Clear;

  // This does not work, for obvious reasons. I get a "list out of 
  // bounds [3] for this one.
  for i:=0 to OSC_Series.Count - 1 do OSC_Series.Delete[0];

  // It seems this should work, but again I get the out of bounds [0]  
  // error.
  repeat
    OSC_Series.Delete(0);
  until OSC_Series.Count = 0;

  // This works. Don't ask me why.
  showmessage('A - '+inttostr(OSC_Series.Count));
  OSC_Series.Clear;
  showmessage('B - '+inttostr(OSC_Series.Count));

  // This also works.
  sleep(2000);
  OSC_Series.Clear;

  // This does not work.
  sleep(1000);
  OSC_Series.Clear;

end;
显然,我很难过。

2 个答案:

答案 0 :(得分:1)

这有点像代码正在使用一个已被破坏的对象(OSC_Series),然后内存被重新用于其他东西。然后,当您使用对该内存的陈旧引用时,您会得到意外且不可预测的结果。

OSC_Series免费在哪里?

我会检查所有这些地方,并确保您免费使用OSC_Series参考后

另请注意,由于该系列由表单拥有,因此表单本身可能会在事件摧毁其拥有的组件(包括此系列)之后在事件中执行代码。

答案 1 :(得分:1)

好吧,愚蠢而不是愚蠢。

我试验了showmessage声明的位置。我发现如果该语句出现在OSC_Series.Clear语句之后,我只能避免错误。我继续移动该语句,直到调用AnalysisRefresh例程之后,该例程位于按钮的OnClick事件处理程序中。这意味着刷新,启用或更新例程中的所有代码都没有导致这种情况。

退一步,如果AnalysisRefresh例程失败,则会向用户显示一条消息。关闭该框后,调用OSC_Series.Clear。如果我通过按键盘上的SPACE或ENTER关闭该框...没有错误。如果我使用鼠标,请输入错误。

鼠标后面的图表有一个OnMouseMove事件,我在状态栏上显示鼠标位置。如果鼠标靠近绘图点,我也会显示提示。单击带有鼠标的消息框以关闭它后,将调用OnMouseMove事件,当它到达可显示提示的位置时,绘制的点将消失,并且......错误。

所以,这似乎是一个几乎随机的错误,但事实并非如此。触发器完全在其他地方。那是你我的尝试/除了块没有捕获错误。 EurekaLog正在捕捉它,但是远远不同的程序。 (Deltics的答案非常接近。)

感谢您的帮助和建议。

当有几天我可以毫无问题地推出数百行代码时,就会出现这种情况,然后会出现类似这样的事情并且花了我两天的时间。