Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi Canvas.textout不´;显示新系列后不显示文本_Delphi_Teechart - Fatal编程技术网

Delphi Canvas.textout不´;显示新系列后不显示文本

Delphi Canvas.textout不´;显示新系列后不显示文本,delphi,teechart,Delphi,Teechart,因此,我要做的是在onmousemove事件中,使用以下代码在teechart图表上显示鼠标指针的x和y值: oscilografia.Repaint; if ((x>236) and (x<927)) and ((y>42) and (y<424)) then begin oscilografia.Canvas.Brush.Style := bsSolid; oscilografia.Canvas.Pen.Color := clBlack; oscilog

因此,我要做的是在onmousemove事件中,使用以下代码在teechart图表上显示鼠标指针的x和y值:

oscilografia.Repaint;

if ((x>236) and (x<927)) and ((y>42) and (y<424)) then
begin
  oscilografia.Canvas.Brush.Style := bsSolid;
  oscilografia.Canvas.Pen.Color := clBlack;
  oscilografia.Canvas.Brush.Color := clWhite;
  oscilografia.Canvas.TextOut(x+10,y,datetimetostr(oscilografia.Series[0].XScreenToValue(x))+','+FormatFloat('#0.00',oscilografia.series[0].YScreenToValue(y)));
  edit1.Text:=inttostr(x)+'  '+inttostr(y);
end;
oscilografia.Repaint;

如果((x>236)和(x42)和(y),则基本问题取决于绘制的工作方式。窗口没有持久的绘制表面。下次系统需要重新绘制时,您在窗口上绘制的内容将被覆盖

您需要安排所有绘制都响应
WM_PAINT
消息。在Delphi术语中,这通常意味着您将把绘制代码放在覆盖的
PAINT
方法中

所以基本的过程是这样的:

  • 派生图表控件的子类,并在该类中重写
    Paint
    。调用继承的
    Paint
    方法,然后执行代码以显示所需的文本
  • OnMouseMove
    事件处理程序中,如果检测到鼠标坐标文本需要更新,请在图表上调用
    Invalidate
  • 调用
    Invalidate
    会将该窗口标记为脏,当下一个绘制周期发生时,将执行
    paint
    中的代码
  • 更重要的是,当发生任何其他强制绘制循环的情况时,例如对图表的其他修改,绘制代码将再次执行
  • 注意,作为子分类的一种替代方法,您可能可以在AfterDraw上使用
    TChart
    事件
    。但我不是
    TChart
    方面的专家,因此不确定。尽管主要要点如我上面所述。

    从中,我看到您遵循了。
    注意,它不绘制任何矩形;它只绘制文本,因此我不确定鼠标后面是什么框。
    另请注意,示例调用
    Invalidate
    ,如中所示。 下面是同一示例的修改版本,在文本前绘制一个矩形

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        Series1.FillSampleValues(10);
        Chart1.View3D := False;
    end;
    
    procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: Integer);
    var tmpL,tmpL2,ClickedValue : Integer;
        tmpWidth, tmpHeight: Integer;
        tmpText: string;
    begin
        clickedvalue := -1;
        tmpL2:= -1;
    
        With Chart1 do
        begin
            If (Series1.Clicked(X, Y) <> -1) And (not OnSeriesPoint) Then
            begin
                Canvas.Brush.Style := bsSolid;
                Canvas.Pen.Color := clBlack;
                Canvas.Brush.Color := clWhite;
                tmpText:=FormatFloat('#.00',Series1.XScreenToValue(x))+','+FormatFloat('#.00',Series1.YScreenToValue(y));
                tmpWidth:=Canvas.TextWidth(tmpText)+10;
                tmpHeight:=Canvas.TextHeight(tmpText);
                Canvas.Rectangle(x+5, y, x+tmpWidth, y+tmpHeight);
                Canvas.TextOut(x+10,y,tmpText);
                OnSeriesPoint := True;
                ClickedValue:= Series1.Clicked(x,y);
            End;
    
            //Repaint Chart to clear Textoutputted Mark
            If (ClickedValue=-1) And (OnSeriesPoint) Then
            begin
                OnSeriesPoint := False;
                Invalidate;
            End;
    
            tmpL := Chart1.Legend.Clicked(X, Y);
    
            If (tmpL <> -1) And ((tmpL <> tmpL2) Or (not OnLegendPoint)) Then
            begin
                repaint;
                Canvas.Brush.Color := Series1.LegendItemColor(tmpL);
                Canvas.Rectangle( X, Y, X + 20, Y + 20);
                Canvas.Brush.Color := clWhite;
                Canvas.TextOut(x+15,y+7,FormatFloat('#.00',Series1.XValues.Items[Series1.LegendToValueIndex(tmpl)]));
                tmpL2 := tmpL;
                OnLegendPoint := True;
            End;
    
            If (tmpL2 = -1) And (OnLegendPoint) Then
            begin
                OnLegendPoint := False;
                Invalidate;
            End;
        End;
    End;
    
    过程TForm1.FormCreate(发送方:TObject);
    开始
    系列1.填充样本值(10);
    Chart1.View3D:=假;
    结束;
    程序TForm1.Chart1MouseMove(发送方:TObject;班次:TSHIFFSTATE;X、,
    Y:整数);
    var tmpL,tmpL2,点击值:整数;
    tmpWidth,tmpHeight:整数;
    tmpText:字符串;
    开始
    点击值:=-1;
    tmpL2:=-1;
    用Chart1做什么
    开始
    如果(系列1.单击(X,Y)-1)和(非体验点),则
    开始
    Canvas.Brush.Style:=bsSolid;
    Canvas.Pen.Color:=clBlack;
    Canvas.Brush.Color:=clWhite;
    tmpText:=FormatFloat('#.00',Series1.XScreenToValue(x))+,'+FormatFloat('#.00',Series1.YScreenToValue(y));
    tmpWidth:=Canvas.TextWidth(tmpText)+10;
    tmpHeight:=Canvas.TextHeight(tmpText);
    画布矩形(x+5,y,x+tmpWidth,y+tmpHeight);
    TextOut(x+10,y,tmpText);
    OnSeriesPoint:=真;
    ClickedValue:=系列1.点击(x,y);
    结束;
    //重新绘制图表以清除文本输出标记
    如果(ClickedValue=-1)和(OnSeriesPoint),则
    开始
    OnSeriesPoint:=假;
    使无效
    结束;
    tmpL:=Chart1.Legend.Clicked(X,Y);
    如果(tmpL-1)和((tmpL-tmpL2)或(不仅仅是端点)),那么
    开始
    重新油漆;
    Canvas.Brush.Color:=系列1.LegendItemColor(tmpL);
    画布矩形(X,Y,X+20,Y+20);
    Canvas.Brush.Color:=clWhite;
    TextOut(x+15,y+7,FormatFloat('#.00',Series1.XValues.Items[Series1.LegendToValueIndex(tmpl)]);
    tmpL2:=tmpL;
    OnLegendPoint:=真;
    结束;
    如果(tmpL2=-1)和(OnLegendPoint),则
    开始
    OnLegendPoint:=False;
    使无效
    结束;
    结束;
    结束;
    
    但问题是文本所在的框出现了,但文本没有。框和文本使用Canvas.TextOut函数绘制。我遵循了本教程中的代码:您遵循的教程显然给了您不好的建议,原因在我的回答中。您对Windows绘制和打印了解多少
    WM\u PAINT
    ?什么都没有。但是你怎么解释我在图例上显示一个新系列后代码才停止工作的事实呢?因为这迫使绘制循环。你不认为你应该了解
    WM\u PAINT
    以及如何在Windows中进行绘制吗?如果你要最小化你的形状,我会假设同样的情况会发生然后再次还原,或者甚至将另一个窗口拖到它上面。当绘制周期到来时会发生什么?重新绘制图表,而不是文本。另一种解决方案是使用OnAfterDraw绘制文本。文本和位置都可以存储在OnMouseMove的全局变量中。这就是问题的关键所在,不是吗?哟你刚才重复了问题中的代码所犯的错误。很抱歉,我试图获得最小的代码来重现问题。你的答案是好的(我投了赞成票)。我只是想知道@gabriel在做什么,以使该框跟随他的鼠标而不显示文本。顺便说一句,你应该提及(可能是在你的用户名中),您是一名Steema开发人员。这将是您在这里帮助的人的有用知识。