在開發視窗應用程式時,如何有效呈現表格型資料是一個常見需求。Pascal的Delphi環境提供了StringGrid控制項,這是一個強大的工具,可以用於顯示和收集表格式的字串資料。
StringGrid的基本屬性與操作
StringGrid控制項提供了一個直觀的網格介面,可用於顯示二維資料。以下是使用StringGrid的基本步驟:
// 建立一個具有3列5行的StringGrid
procedure CreateBasicGrid;
begin
sgdMy.ColCount := 3;
sgdMy.RowCount := 5;
sgdMy.FixedCols := 1;
sgdMy.FixedRows := 1;
// 設定固定列和行的顏色
sgdMy.FixedColor := clGreen;
// 設定其他單元格的顏色
sgdMy.Color := clWhite;
// 填充一些單元格
sgdMy.Cells[0, 0] := '專案';
sgdMy.Cells[1, 0] := '數量';
sgdMy.Cells[2, 0] := '單價';
sgdMy.Cells[0, 1] := '筆記本';
sgdMy.Cells[1, 1] := '5';
sgdMy.Cells[2, 1] := '15';
end;
這段程式碼示範瞭如何建立和設定基本的StringGrid控制項。主要步驟包括:
- 設定網格的列數(ColCount)和行數(RowCount)
- 設定固定列數(FixedCols)和固定行數(FixedRows),這些區域通常用於顯示標題
- 設定固定區域和普通單元格的顏色
- 使用Cells屬性填充特定單元格的內容
在StringGrid中,索引從0開始,Cells[0, 0]表示左上角的單元格。第一個索引是列號,第二個索引是行號。
動態建立與設定StringGrid
在實際應用中,我們通常需要根據使用者輸入或程式需求動態設定StringGrid。以下是一個完整的例子,展示如何根據使用者輸入建立網格:
procedure GetGridParam(var n1, n2, n3, n4: integer);
begin
n1 := StrToInt(frmGrid.edtLine.Text);
n2 := StrToInt(frmGrid.edtStolb.Text);
n3 := StrToInt(frmGrid.edtFline.Text);
n4 := StrToInt(frmGrid.edtFstolb.Text);
end;
procedure CreateGrid(n1, n2, n3, n4: integer);
begin
frmGrid.sgdMy.RowCount := n2;
frmGrid.sgdMy.ColCount := n1;
frmGrid.sgdMy.FixedCols := n4;
frmGrid.sgdMy.FixedRows := n3;
end;
procedure TfrmGrid.btnTablClick(Sender: TObject);
var
nl, ns, nfl, nfs: integer;
begin
GetGridParam(nl, ns, nfl, nfs); // 取得網格引數
CreateGrid(nl, ns, nfl, nfs); // 建立指定引數的網格
end;
procedure TfrmGrid.btnCelRedClick(Sender: TObject);
begin
frmGrid.sgdMy.Color := clRed;
end;
procedure TfrmGrid.btnFCGreenClick(Sender: TObject);
begin
frmGrid.sgdMy.FixedColor := clGreen;
end;
這段程式碼展示瞭如何根據使用者輸入動態建立和設定StringGrid:
GetGridParam
函式從四個文字框中取得使用者輸入的引數:列數、行數、固定列數和固定行數。CreateGrid
函式使用這些引數設定StringGrid控制項。btnTablClick
是按鈕點選事件處理程式,它呼叫上述兩個函式來建立網格。btnCelRedClick
和btnFCGreenClick
是兩個按鈕的事件處理程式,分別用於將普通單元格設為紅色和固定單元格設為綠色。
這種動態設定方式使應用程式更具靈活性,能夠適應不同的資料展示需求。
StringGrid的實用屬性一覽
以下是StringGrid的一些核心屬性,瞭解這些有助於更好地控制網格的外觀和行為:
BorderStyle
: 指定網格邊框的外觀(bsNone無邊框,bsSingle 1畫素邊框)ColCount
: 網格列數DefaultColWidth
: 預設列寬RowCount
: 網格行數DefaultRowHeight
: 預設行高Color
: 控制單元格顏色FixedCols
: 控制固定列數FixedRows
: 控制固定行數FixedColor
: 控制固定單元格的顏色GridHeight
: 網格高度GridWidth
: 網格寬度GridLineWidth
: 指定網格線寬度
實戰應用:實驗資料分析
下面是一個實際應用範例,展示如何使用StringGrid來記錄和分析物理實驗資料:
procedure TfrmExperiment.btnCalculateClick(Sender: TObject);
var
i, expCount, scaleInterval: Integer;
value, result, minResult, maxResult: Double;
minIndex, maxIndex: Integer;
begin
// 取得實驗次數和刻度間隔
expCount := StrToInt(edtExpCount.Text);
scaleInterval := StrToInt(edtScaleInterval.Text);
// 設定網格引數
sgdExperiment.Row
Delphi矩陣操作與StringGrid實戰技巧
在Delphi應用程式開發中,處理表格式資料是常見的需求。StringGrid元件提供了絕佳的視覺化方式來呈現和操作二維資料結構。本文將透過實際範例,帶領你探索StringGrid的強大功能以及相關的矩陣操作技巧。
StringGrid基礎操作例項
首先,讓我們從一個基本的StringGrid操作範例開始。這個範例展示如何建立一個具有使用者指定行列數的格子,並填入隨機數值,然後計算每一列中負數元素的數量。
實作第一個StringGrid應用
在這個範例中,我們需要:
- 兩個文字輸入框來設定列數和行數
- 一個StringGrid來顯示資料
- 一個TMemo元件來顯示結果
- 兩個按鈕來執行操作
以下是按鈕點選事件的處理程式碼:
procedure TForm1.Button1Click(Sender: TObject);
var
i, j, n, m: integer;
begin
n := StrToInt(Edit1.Text);
m := StrToInt(Edit2.Text);
StringGrid1.RowCount := n;
StringGrid1.ColCount := m;
for i := 0 to n-1 do
for j := 0 to m-1 do
StringGrid1.Cells[j, i] := IntToStr(Random(100)-50);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i, j, n, m, k: integer;
begin
n := StringGrid1.RowCount;
m := StringGrid1.ColCount;
for i := 0 to n-1 do
begin
k := 0;
for j := 0 to m-1 do
if StrToInt(StringGrid1.Cells[j, i]) < 0 then
k := k+1;
Memo1.Lines.Append(IntToStr(k));
end
end;
第一個程式中,Button1Click
事件處理程式執行以下操作:
- 從兩個文字輸入框中取得行數(
n
)和列數(m
) - 設定StringGrid的行數和列數
- 使用巢狀迴圈遍歷每個單元格,填入-50到49之間的隨機整數
第二個程式中,Button2Click
事件處理程式執行以下操作:
- 取得StringGrid的實際行數和列數
- 逐行檢查每個單元格的值
- 計算每行中負數的個數
- 將結果附加到Memo控制項中顯示
這個範例展示瞭如何基本操作StringGrid,
二維陣列的實作與應用
在程式設計過程中,二維陣列是一種常用與重要的資料結構,尤其適合處理表格式資料。在Pascal語言中,二維陣列有其獨特的實作方式,接下來將介紹如何建立和操作二維陣列,以及如何將其與視覺化控制項結合使用。
二維陣列的宣告與初始化
在Pascal中,我們可以透過兩種方式宣告二維陣列:一種是直接使用二維陣列語法,另一種則是將二維陣列視為「陣列的陣列」。以下是後者的實作方式:
Const
n = 3; // 列數
m = 6; // 行數
Type
array_1 = array[1..n] of integer; // 定義一維陣列類別
array_2 = array[1..m] of array_1; // 定義二維陣列類別(陣列的陣列)
這段程式碼首先定義了常數n和m,分別代表陣列的列數和行數。接著定義了兩個陣列類別:array_1
是一個包含n個整數的一維陣列;array_2
則是包含m個array_1
型別的陣列,形成了一個m×n的二維陣列結構。在Pascal中,這種「陣列的陣列」是實作二維陣列的常用方式,區別於其他語言中的直接二維陣列宣告。
隨機填充二維陣列
建立二維陣列後,常見的操作是填充資料。以下範例展示如何用隨機數填充二維陣列:
Var
C: array_2;
Begin
FillArray(c); // 填充陣列C
TableOutput(c); // 將陣列C輸出到表格
end;
procedure FillArray(var arr: array_2);
var
i: integer;
begin
Randomize; // 初始化隨機數產生器
for i:=1 to m do // 對每一行進行迴圈
FillColumn(arr[i]); // 填充第i行
end;
procedure FillColumn(var col: array_1);
var
j: integer;
begin
for j:=1 to n do // 對每一列進行迴圈
col[j] := Random(21)-10; // 產生-10到10之間的隨機數
end;
這段程式碼展示瞭如何填充二維陣列。主程式呼叫FillArray
函式處理整個陣列,而FillArray
則針對每一行呼叫FillColumn
函式。在FillColumn
中,透過Random(21)-10
產生-10到10之間的隨機整數(這是因為Random(21)
會產生0到20的隨機數)。Randomize
函式確保每次執行程式時都會產生不同的隨機數序列,這在實際應用中很重要,避免每次執行都得到相同的「隨機」結果。
使用StringGrid顯示二維陣列
在Delphi/Pascal中,StringGrid是顯示表格資料的理想控制項。以下是如何將二維陣列輸出到StringGrid的方法:
procedure TableOutput(arr: array_2);
var
i, j: integer;
begin
frm2arr.sgdMy.FixedCols := 0; // 設定固定列數為0
frm2arr.sgdMy.FixedRows := 0; // 設定固定行數為0
frm2arr.sgdMy.ColCount := m; // 設定總列數
frm2arr.sgdMy.RowCount := n; // 設定總行數
for i := 1 to m do
for j := 1 to n do
frm2arr.sgdMy.Cells[i-1, j-1] := IntToStr(arr[i][j]);
end;
這段程式碼展示瞭如何將二維陣列資料顯示在StringGrid控制項中。首先設定StringGrid的基本屬性:FixedCols
和FixedRows
設為0表示沒有固定的標題列和標題行,ColCount
和RowCount
則設定為陣列的維度。接著使用巢狀迴圈,將陣列中的每個元素轉換為字串並填入對應的儲存格。注意索引轉換:Pascal陣列索引從1開始,而StringGrid索引從0開始,所以要減1進行調整。
陣列轉置顯示
有時候,我們需要轉置陣列再顯示,這意味著將陣列的行和列互換:
procedure TableOutput(arr: array_2);
var
i, j: integer;
begin
frm2arr.SgdMy.ColCount := n; // 設定列數為陣列的列數
frm2arr.SgdMy.RowCount := m; // 設定行數為陣列的行數
for i := 1 to n do
for j := 1 to m do
frm2arr.SgdMy.Cells[i-1, j-1] := IntToStr(arr[j][i]);
end;
這個版本的TableOutput
函式實作了陣列的轉置顯示。與前一個版本的主要區別在於:1) StringGrid的維度設定為n列m行,與原始陣列的m列n行相反;2) 存取陣列元素時使用arr[j][i]
而非arr[i][j]
,實作了行列互換。這種轉置技巧在處理矩陣運算或改變資料呈現方式時非常有用。
二維陣列實作練習
以下是幾個二維陣列的實作練習,可以幫助鞏固對二維陣列操作的理解。
練習1:陣列統計分析
填充一個M列N行的二維陣列,範圍由使用者輸入,然後計算:
- 所有元素的總和
- 最大和最小元素
- 每列元素的總和
這個練習需要實作多種陣列操作:填充、遍歷、查詢最值、分組計算等。
練習2:實數陣列與行和
填充一個N行M列的實數陣列,範圍由使用者輸入,然後:
- 將陣列輸出到StringGrid
- 計算每行元素的總和並顯示在每行的額外儲存格中
這個練習結合了陣列操作和UI顯示技巧,特別適合練習StringGrid的進階使用。
日期與時間處理
在許多應用程式中,日期和時間的處理是基本需求。Delphi提供了強大的日期時間處理功能,下面將介紹其核心概念和常用操作。
TDateTime資料型別
Delphi中使用特殊的TDateTime
資料型別來處理日期和時間:
Var
a, b: TDateTime;
TDateTime
本質上是一個雙精確度浮點數,其整數部分代表自1899年12月30日以來經過的天數,小數部分則代表一天中的時間比例。例如,0.5代表中午12點,0.75代表下午6點。
這種設計使日期時間計算變得簡單:
- 兩個日期相減得到的是天數差
- 日期加上或減去一個數字,結果是向前或向後推算的日期
需要注意的是,處理負值TDateTime
時需要特別小心。例如,1899年12月29日早上6點表示為-1.25,而不是-0.75(-1+0.25)。
日期時間解碼函式
Delphi提供了多種函式來解析TDateTime
值:
// 解析日期部分
DecodeDate(Date: TDateTime; var Year, Month, Day: Word);
// 解析時間部分
DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word);
DecodeDate
函式將TDateTime
值分解為年、月、日三個部分。例如,如果變數A儲存的日期是2008年3月1日,則呼叫DecodeDate(A, y, m, d)
後會得到y=2008, m=3, d=1。
DecodeTime
函式則將TDateTime
值分解為時、分、秒、毫秒四個部分。這兩個函式在需要單獨操作日期或時間的各個部分時非常有用。
取得當前日期時間
取得當前日期和時間是常見需求:
Var
a, b, c: TDateTime;
Begin
a := Date; // 回傳當前日期
b := Time; // 回傳當前時間
c := Now; // 回傳當前日期和時間
End;
這三個函式分別取得系統當前的日期、時間或兩者。它們依賴於電腦的系統設定,因此如果系統日期時間不準確,這些函式回傳的值也會不準確。在需要高精確度時間的應用中,可能需要考慮與標準時間源同步。
日期時間與字串轉換
Delphi提供了完整的日期時間與字串互相轉換的函式:
// 時間轉字串
TimeToStr(t: TDateTime): String;
// 日期轉字串
DateToStr(t: TDateTime): String;
// 日期時間轉字串
DateTimeToStr(t: TDateTime): String;
// 字串轉時間
StrToTime(S: String): TDateTime;
// 字串轉日期
StrToDate(S: String): TDateTime;
// 字串轉日期時間
StrToDateTime(S: String): TDateTime;
這些函式實作了TDateTime
與字串格式之間的互相轉換。格式化時會使用系統的地區設定,如LongTimeFormat
、ShortDateFormat
等。例如,DateToStr
可能會將日期格式化為'03:04:2015’。
從字串轉換時需要注意一些規則:
- 時間字串可以省略秒數,如'9:10’會被轉換為'9:10:00'
- 日期必須有效
- 如果年份只有兩位數,會被自動轉換為1930-2030範圍內的年份
- 如果未指定年份,會使用當前年份
- 日期和月份必須指定
其他日期時間函式
Delphi還提供了許多其他實用的日期時間函式:
// 取得星期幾(1=星期日,2=星期一,...)
DayOfWeek(Date: TDateTime): Word;
// 解析日期並判斷是否閏年
DecodeDateFully(Date: TDateTime; var Year, Month, Day, DOW: Word): Boolean;
// 從年月日合成日期
EncodeDate(Year, Month, Day: Word): TDateTime;
// 從時分秒毫秒合成時間
EncodeTime(Hour, Min, Sec, Msec: Word): TDateTime;
這些函式提供了更專門的日期時間處理功能。DayOfWeek
回傳星期幾的索引值,DecodeDateFully
不僅解析日期還回傳是否閏年,EncodeDate
和EncodeTime
則是從各個部分合成日期或時間值。這些函式在排程、日曆或需要精確日期計算的應用中特別有用。
日期時間運算
TDateTime
型別支援多種運算:
- 兩個日期相減得到的是中間相差的天數
- 日期加上或減去整數,相當於向前或向後計算對應天數的日期
- 時間可以透過多種方式進行計算
例如,計算1.5小時後的時間有兩種方式:
// 方式1:直接加上天數的比例(1.5小時等於1.5/24天)
新時間 := Time + 1.5/24;
// 方式2:使用時間字串轉換
新時間 := Time + StrToTime('1:30');
這兩種計算方式都能達到相同的效果。第一種方式直接使用了TDateTime
的特性,將1.5小時轉換為天的比例(1.5/24);第二種方式則更直觀,直接使用時間字串。選擇哪種方式主要取決於程式的具體需求和開發者的偏好。
日期時間應用練習
讓我們透過兩個實際練習來加深對日期時間處理的理解。
練習1:找出最年輕的
時間控制的藝術:計時器元件的基礎與應用
在程式開發中,時間控制是一個常見但又極為重要的需求。無論是建立動畫效果、執行定期任務,還是處理時間相關的計算,計時器都是不可或缺的工具。在這篇文章中,我將探討計時器的使用方法、核心概念以及進階應用技巧。
計時器的基本原理與特性
計時器(Timer)是一個能夠在設定的時間隔後觸發事件的元件。當開發需要在特定時間後執行某些程式碼時,計時器提供了一個簡潔而強大的解決方案。
在介面開發工具中,計時器通常是一個不可見的元件,它在執行時不會在使用者介面上顯示,但會在後台持續計時並觸發已設定的事件。
計時器的核心屬性包括:
Enabled 屬性
這個布林值屬性決定計時器是否運作。當設為 True 時,計時器開始運作;設為 False 時,計時器停止。
Interval 屬性
這個屬性指定計時器的反應時間,單位為毫秒。例如,設定為 1000 表示計時器每秒觸發一次事件;設定為 5000 則表示每 5 秒觸發一次。
計時器的基本應用
讓我們從一個簡單的例子開始。假設我們想要在程式啟動 5 秒後將表單背景變為紅色:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
form1.Color := clRed;
end;
在這個例子中,我們需要將計時器的 Interval 屬性設為 5000(5秒),當計時器觸發時,表單的背景色將變為紅色。
這段程式碼定義了計時器觸發事件的處理程式。當計時器達到設定的時間隔(5000毫秒)時,系統會自動呼叫此程式,執行 form1.Color := clRed
這行程式碼,將表單背景顏色設為紅色。這是最基本的計時器應用,展示瞭如何在特定時間後執行動作。
動態控制計時器
計時器的真正威力在於我們可以在程式執行過程中動態控制它。例如,我們可以在使用者點選按鈕後才啟動計時器:
procedure TForm1.Button1Click(Sender: TObject);
begin
timer1.Enabled := true;
end;
在這種情況下,我們需要在設計時將計時器的 Enabled 屬性設為 False。程式啟動後,計時器不會運作,直到使用者點選按鈕,計時器才會啟動,並在 5 秒後將表單變為紅色。
這段程式碼展示瞭如何透過按鈕點選事件來控制計時器的啟動。當使用者點選按鈕時,程式將計時器的 Enabled 屬性設為 true,從而啟動計時器。這種方式讓開發者能夠根據使用者操作來精確控制計時器的行為,而不是讓計時器在程式啟動時就立即運作。
創造動態視覺效果
計時器的一個常見應用是創造動態視覺效果。讓我們修改之前的例子,使表單背景色每隔一段時間就隨機變化:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
form1.Color := 256*256*random(256) + 256*random(256) + random(256);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
timer1.Enabled := true;
timer1.Interval := 1500;
end;
在這個例子中,每 1.5 秒,表單的背景色就會變成一個隨機顏色。
計時器事件處理程式中的程式碼使用 random(256)
函式生成三個隨機數值(分別對應 RGB 色彩模型的紅、綠、藍三個分量),然後透過數學運算將它們組合成一個顏色值。這種技術可以創造出豐富多彩的視覺效果。
按鈕點選事件不僅啟動了計時器,還將計時器的間隔設定為 1500 毫秒(1.5秒),這樣每隔 1.5 秒顏色就會變換一次。這展示瞭如何在執行時動態調整計時器的屬性。
控制計時器的停止
要停止計時器,我們只需要將 Enabled 屬性設為 False:
procedure TForm1.Button2Click(Sender: TObject);
begin
timer1.Enabled := false;
end;
這樣,我們就可以透過一個按鈕啟動計時器,透過另一個按鈕停止它。
這個簡單的程式碼片段展示瞭如何停止計時器的執行。當使用者點選第二個按鈕時,計時器的 Enabled 屬性被設定為 false,此時計時器停止運作,不再觸發事件。這種控制方式讓使用者能夠完全掌控程式中的時間相關功能。
單次觸發計時器
有時我們只希望計時器觸發一次,而不是持續觸發。這可以透過在計時器事件中關閉計時器來實作:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
form1.Color := 256*256*random(256) + 256*random(256) + random(256);
timer1.Enabled := false;
end;
這樣,計時器會觸發一次,改變表單顏色,然後自動關閉。
這個程式碼片段展示瞭如何建立"一次性"計時器。關鍵在於在計時器事件處理程式的最後一行,將計時器自身的 Enabled 屬性設為 false。這樣,計時器在執行完指定動作後會立即停止,不再繼續觸發。這種模式非常適合只需執行一次的延時操作。
使用多個計時器
更複雜的時間控制需求可能需要使用多個計時器協同工作。例如,我們可以使用一個計時器來改變顏色,使用另一個計時器來在特定時間後停止第一個計時器:
procedure TForm1.Button1Click(Sender: TObject);
begin
timer1.Enabled := true;
timer1.Interval := 1500;
timer2.Enabled := true;
timer2.Interval := 20000;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
form1.Color := 256*256*random(256) + 256*random(256) + random(256);
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
timer1.Enabled := false;
timer2.Enabled := false;
end;
在這個例子中,點選按鈕後,表單顏色會開始每 1.5 秒變化一次,然後在 20 秒後停止變化。
這個範例展示了多計時器協作的強大功能。第一個計時器(timer1)負責每 1.5 秒改變一次表單顏色,而第二個計時器(timer2)則負責在 20 秒後停止整個過程。
按鈕點選事件同時啟動兩個計時器,但設定了不同的時間隔。第二個計時器的事件處理程式會同時停用兩個計時器,確保在 20 秒後整個過程完全結束。這種多計時器協作模式可以實作更複雜的時間控制邏輯。
建立移動效果
計時器還可以用來建立移動效果。例如,我們可以使一個文字框從左向右移動:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
edit1.Left := edit1.Left + 15;
end;
每次計時器觸發時,文字框會向右移動 15 個畫素,建立一個平滑的移動效果。
這段程式碼展示瞭如何使用計時器建立動畫效果。每次計時器觸發時,程式會增加文字框的 Left 屬性值(水平位置),使其向右移動 15 個畫素。如果計時器設定為較短的間隔(如 50 毫秒),這種移動會看起來非常平滑,形成一個簡單但有效的動畫。這種技術可以擴充套件到更複雜的動畫和遊戲開發中。
實用的計時器應用範例
讓我們來看一些實用的計時器應用範例,這些例子展示了計時器在不同場景下的強大功能。
數字時鐘的實作
數字時鐘是計時器的一個典型應用。以下是一個簡單的數字時鐘實作:
procedure TForm1.Timer1Timer(Sender: TObject);
var
CurrentTime: TDateTime;
TimeStr, DateStr, DayStr: string;
begin
CurrentTime := Now;
TimeStr := FormatDateTime('hh:nn:ss', CurrentTime);
DateStr := FormatDateTime('yyyy-mm-dd', CurrentTime);
case DayOfWeek(CurrentTime) of
1: DayStr := '星期日';
2: DayStr := '星期一';
3: DayStr := '星期二';
4: DayStr := '星期三';
5: DayStr := '星期四';
6: DayStr := '星期五';
7: DayStr := '星期六';
end;
lblTime.Caption := TimeStr;
lblDate.Caption := DateStr;
lblDay.Caption := DayStr;
end;
這段程式碼實作了一個完整的數字時鐘功能。它使用 Now
函式取得當前的日期和時間,然後使用 FormatDateTime
函式將其格式化為時間字元串和日期字元串。
DayOfWeek
函式回傳一個介於 1 到 7 之間的整數,代表星期幾(1 代表星期日,7 代表星期六)。程式使用一個 case 陳述式將這個數值轉換為對應的星期文字。
最後,程式將格式化好的時間、日期和星期幾顯示在對應的標籤上。如果計時器間隔設為 1000 毫秒(1秒),這個時鐘將每秒更新一次,顯示當前的精確時間。
倒計時計時器
倒計時計時器在許多應用中都很有用,如遊戲、測驗或任何需要時間限制的場景:
var
SecondsLeft: Integer;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
SecondsLeft := StrToInt(Edit1.Text);
lblTimer.Color := clWhite;
timer1.Enabled := true;
except
ShowMessage('請輸入有效的秒數!');
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Dec(SecondsLeft);
lblTimer.Caption := IntToStr(SecondsLeft);
if SecondsLeft <= 0 then
begin
lblTimer.Color := clRed;
// 如果到達零,計時器改為計算超時間
SecondsLeft := Abs(SecondsLeft);
end;
end;
這段程式碼實作了一個倒計時計時器,具有超時計算功能。首先,它在按鈕點選事件中從輸入框取得初始秒數,並啟動計時器。程式使用 try-except 塊來確保輸入的是有效的數字。
在計時器事件中,程式每秒減少計數器的值(使用 Dec
函式),並更新標籤顯示當前剩餘時間。當計數器達到或低於零時,標籤的背景色變為紅色,表示時間已經用完。
有趣的是,一旦計數器變為負數,程式使用 Abs
函式將其轉換為正數,這樣就開始計算超時間。這種技術在需要跟蹤超出允許時間的情況下非常有用。