2016-07-13 115 views
2

我想在橢圓中間顯示數字作爲在畫布上繪製的文本。座標將被存儲在數據庫中(橢圓),以及文本值將被存儲在數據庫的另一部分。(Delphi FMX)如何使用Canvas.FillText顯示在橢圓的中間?

我到目前爲止所做的工作是從FMXExpress (Github)開始,我一直在工作w/a示範項目(DrawApp),其中我已經將一些程序從Private改爲Public。這些程序包括StartDrawing(startP:TPointF),EndDrawing(startP:TPointF),DoDraw()這樣我可以從外部單元/對象使用這些函數。該對象使用這些函數與MouseUp/MouseDown配合使用,以及少數屬性,包括fDrawing來區分繪圖是否正在進行以及正在使用的工具(fdEllipse)。

我的主窗體在FormCreate中使用下面的代碼來初始創建fdrawbox:= TMyPaintBox.Create(Rectangle1); Rectangle1位於圖像的頂部,該圖像表示用於顯示身體部位的網格,並且能夠在圖像頂部繪製圓圈。我發現的是,創建文本或橢圓並不難,但爲了創建具有標識符的多個圓來區分圓,就像我剛纔提到的那樣,我想要一個數字來顯示哪個圓是哪個。即使在將來,我也許想改變顏色來顯示哪個圈子要專注。

demonstration for mypaintbox http://www.abatepain.com/abate/OHlbF.jpg

所以下面的代碼(DELPHI FMX)示出了通過利用TRectangle作爲其父創建drawapp。

with fdrawbox do begin 
    Parent := Rectangle1; 
    Visible := True; 
    ForegroundColor := TAlphaColor($FF000000); // 
    BackgroundColor := TAlphaColor($00000000); // 

    FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True; 
    StartDrawing(PointF(100, 100)); 
    EndDrawing(PointF(200, 200)); 
    FuncDraw := TFunctionDraw.fdNone; 

    OnPaint := PaintBox1Paint; 
end; 

使用的最後幾行,創建圈子,但爲了利用fillText方法,我需要使用的OnPaint功能,這是我創建的代碼看起來是這樣的。我相信DrawApp在內部處理OnPaint函數,但它如何處理它仍然是未知的。但爲了打印「Hello Text !!」,它永遠不是必需品。

procedure TMainForm.PaintBox1Paint(Sender: TObject; Canvas: TCanvas); 
begin 
    with Canvas do begin 
    BeginScene(); 
    //Clear(cbbg.Color); 
    Font.Style := []; 
    Font.Size := 12; 
    Fill.Color := TAlphaColors.Red; 
    FillText(TRectF.Create(0, 0, 300, 295), 'Hello Text!!', false, 100, [], TTextAlign.Center, TTextAlign.Center); //TFillTextFlag.RightToLeft 
    EndScene; 
    end; 
    Application.ProcessMessages; 
end; 

有人可以給如何處理這個(可能是一個單一的功能中)在那裏我可以打印多圈,並有相關的文字遵循它的一個例子嗎?我相信在前面的例子中,我可以自己做,但是我必須手動爲文本輸入PointF(對於圓)和TRectF,並且它們都使用不同的值作爲座標。

回答

0

正如您所指出的,TMyPaintBox類不支持文本呈現,也不支持文本輸出的常用屬性,如字體或顏色等。但您可以通過定義私有部分中的字段和要獲取的屬性來自定義字段/設置公開部分的值。

在下面我假定此外字段ftextoutffontsizeffontcolor的具有相應的性質TextOutFontSizeFontColor

要添加以類似繪製其他元素類型的方式呈現文本的功能,請將fdText作爲新的枚舉添加到TFunctionDraw

TFunctionDraw=(fdNone,fdPen,fdLine,fdRectangle,fdEllipse,fdFillBgr,fdBitmapStamp,fdPolyLine, fdText); 

然後在TMyPaintBox.DoDraw一個新的案例選項添加到case ffdraw of例如像:

with vCanvas do 
begin 
BeginScene(); 
case ffdraw of 
    // 
    // other TFunctionDraw enums 
    // 
    TFunctionDraw.fdText: begin 
    {Canvas.}Font.Size := ffonsize; // new field 
    {Canvas.}Fill.Color := ffontcolor; // new field 
    {Canvas.}FillText(r, TextOut, False, 1, [], 
     TTextAlign.Center, TTextAlign.Center); 
    end; 
end; 

編輯:

TFunctionDraw.fdText的到Canvas引用是多餘的。刪除未註釋的參考。要使用的畫布已在with語句中定義(添加到要顯示的代碼中)。哦,我討厭那些with s!

還值得注意的是,如果您只想顯示帶有文本的圓圈,並且不讓用戶在畫布上繪製,則可以使用自己的組件更簡單地實現它。

此外,請勿直接撥打DoDraw。它被Paint調用,只要fdrawbox失效就會觸發它。因此,如果您想強制更新,請撥打invalidate

編輯

的末尾,則可以實現文字渲染,就像元素(使用你的代碼模板)的任何其他圖:

with fdrawbox do begin 
    Parent := Rectangle1; 
    Visible := True; 
    ForegroundColor := TAlphaColor($FF000000); // 
    BackgroundColor := TAlphaColor($00000000); // 

    FuncDraw := TFunctionDraw.fdEllipse; //fdrawbox.fDrawing := True; 
    StartDrawing(PointF(100, 100)); 
    EndDrawing(PointF(200, 200)); 

    FuncDraw := TFunctionDraw.fdText; 
    FontSize := 12; // set new property 
    FontColor := TAlphaColorRec.Red; // set new property 
    TextOut := 'Hello text!'; 
    StartDrawing(PointF(100, 100)); 
    EndDrawing(PointF(200, 200)); 

    FuncDraw := TFunctionDraw.fdNone; 

    invalidate; 
    // OnPaint := PaintBox1Paint; // no need for this 
end; 
+0

我很欣賞你的答案,所以謝謝你。但是我收到了訪問違規。我開始了一個新項目,以確保它不是我的代碼中隱藏的問題。 Project1.exe引發異常類$ C0000005消息'訪問衝突在0x0077dbdc:讀取地址0x00000000'我糾正了一些字體屬性拼寫又名ffonsize,並採取了屏幕抓取。 [鏈接](https://postimg.org/image/cdpak9yw1/)我也嘗試在MyPaintBox.pas中的Create()函數內部預先定義值,但那不起作用。我也試過在不同的地方開始/結束, –

+0

@Barry在哪個AV觸發?您的屏幕抓取鏈接僅顯示「無法顯示此頁面」。 –

+0

這些也是我添加的屬性。我相信錯誤信息與我爲TextOut選擇的數據類型有關。 屬性TextOut:字符串讀取ftextout寫入ftextout; 屬性FontSize:單個讀取ffontsize寫入ffontsize; property FontColor:TAlphaColor read ffontcolor write ffontcolor; [鏈接](https://s32.postimg.org/u0cgfamdh/delphi_exception_error.jpg) –