Зміна кольору осередки в stringgrid при заповненні таблиці
Зміна кольору осередки в StringGrid при заповненні таблиці
Виводжу рішення свого завдання в StringGrid. Необхідно зафарбувати якимось кольором осередку з оптимальним рішенням. Тобто в одному рядку тільки один осередок повинна бути зафарбована.
Як це реалізувати?
а як подія з натисканням клавіші зв'язати?
> А як подія з натисканням клавіші зв'язати?
Подія (OnDrawCell для StringGrid) потрібно задати в інспекторові об'єктів (перейти на вкладку "Events" і там двічі клацнути лівою кнопкою миші на відповідному подію, щоб створився обробник до нього).
А що має відбуватися при натисканні клавіші? Якщо тільки після натискання клавіші повинен оздоблюватися StringGrid, то просто створіть змінну colored = false, а в обробнику клавіші надайте їй true. А в OnDrawCell перевіряйте: якщо colored = true, то фарбуйте.
а при цьому треба використовувати StringGrid.Repaint.
procedure TForm1.StringGrid1DrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
# XA0; if ACol = 0 then # XA0; // зафарбовує першу осередок в рядку
# XA0; begin
# XA0; # XA0; stringGrid1.Canvas.Brush.Color: = clGray;
# XA0; # XA0; stringGrid1.Canvas.FillRect (rect);
# XA0; end;
StringGrid.Repaint ні в якому разі!
> А при цьому треба використовувати StringGrid.Repaint.
Якщо у вас раніше таблиці не оздоблювалась і тепер (наприклад, після натискання на кнопку) ви вирішили, що вона повинна почати оздоблюватися (colored = true), то напевно, не завадить викликати Refresh, інакше таблиця може перемалювати тільки коли це буде потрібно. Але після цього ні Repaint ні Refresh викликати буде не треба (особливо в OnDrawCell) - таблиця буде сама себе малювати в міру необхідності.
Чомусь закрашивается вся таблиця і тексту не видно:
procedure Tmain.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
if coloured = true then
begin
st.Canvas.Brush.Color: = clGreen;
st.Canvas.FillRect (rect);
end;
end;
procedure Tmain.Button9Click (Sender: TObject);
var i, j: integer;
begin
coloured: = false;
for i: = 0 to st.RowCount-1 do
for j: = 0 to st.ColCount-1 do
begin
# XA0; coloured: = false;
# XA0; if (j = opt [i]) then coloured: = true;
# XA0; st.Cells [j, i]: = floattostr (reshc [i, j]) + "" + floattostr (resht [i, j]);
# XA0; st.Refresh;
end;
end;
ненарісованного тексту і не повинно бути видно
Ведмедик П'ятачок
а більш детально?
Умова, коли потрібно зафарбовувати осередок а коли немає потрібно поміщати в OnDrawCell. Ось приклад:
procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; colored: = True;
# XA0; st.Refresh;
end;
procedure TForm1.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
# XA0; if (colored) and (ACol mod 2 = ARow mod 2)
# XA0; then st.Canvas.Brush.Color: = clWhite
# XA0; else st.Canvas.Brush.Color: = clBlack;
куди ще щось докладніше?
текст не намальований.
що має бути при цьому видно?
І. Павло
Начебто у мене так все і є крім цього умови (ACol mod 2 = ARow mod 2)
тоді він за шаховим зафарбовує
Ведмедик ХМЛ
але після натискання клавіші у мене адже таблиця заповнюється
і чого?
ти її (таблицю) не бачиш?
Ведмедик ХМЛ
бачу але осередки порожні (зелені) хоча я в них текст додаю
> Basilisk # XA0; (05.04.11 14:12) [10]
>
> Ведмедик П'ятачок
> А більш детально?
Подробиці в довідці і у викладача.
> Basilisk # XA0; (05.04.11 14:19) [14]
>
> Ведмедик ХМЛ
> Але після натискання клавіші у мене адже таблиця заповнюється
Заповнення таблиці і малювання її ж операції різні і незалежні.
> Начебто у мене так все і є крім цього умови (ACol mod
> 2 = ARow mod 2)
>
> Тоді він за шаховим зафарбовує
Замість цього умови вставте своє: "if (j = opt [i])". Зараз воно у вас в Button9Click, але має бути в stDrawCell. Спершу виконується Button9Click і встановлює colored в true. Потім, при необхідності перемальовування, виконується stDrawCell, в якому ви повинні перевірити: чи потрібно осередок прикрасити і прикрасити її.
бачу але осередки порожні (зелені) хоча я в них текст додаю
Все що ти намалював - ти бачиш.
Все чого ти не малював - ти не бачиш.
Принаймні не повинен бачити в нормальному стані свідомості.
> Осередки порожні (зелені) хоча я в них текст додаю
Ось з висновком тексту:
procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; st.Cells [1, 1]: = "aaa";
# XA0; colored: = True;
# XA0; st.Refresh;
end;
procedure TForm1.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
# XA0; if (colored) and (ACol mod 2 = ARow mod 2)
# XA0; then st.Canvas.Brush.Color: = clWhite
# XA0; else st.Canvas.Brush.Color: = clBlack;
# XA0; st.Canvas.FillRect (Rect);
# XA0; st.Canvas.TextRect (Rect, Rect.Left, Rect.Top, st.Cells [ACol, ARow]);
end;
Навіть можна без "st.Canvas.FillRect (Rect);", тому що TextRect сам фон малює.
procedure Tmain.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
var i, j: integer;
begin
for i: = 0 to st.RowCount-1 do
for j: = 0 to st.ColCount-1 do
begin
if (coloured = true) and (j = opt [i]) then # XA0; st.Canvas.Brush.Color: = clGreen
else st.Canvas.Brush.Color: = clWhite;
st.Canvas.FillRect (Rect);
st.Canvas.TextRect (Rect, Rect.Left, Rect.Top, st.Cells [ACol, ARow]);
end;
end;
procedure Tmain.Button9Click (Sender: TObject);
var i, j: integer;
begin
for i: = 0 to st.RowCount-1 do
for j: = 0 to st.ColCount-1 do
begin
# XA0; st.Cells [j, i]: = floattostr (reshc [i, j]) + "" + floattostr (resht [i, j]);
# XA0; coloured: = true;
# XA0; st.Refresh;
end;
Текст видно, але осередки все одно все зафарбовує
> For i: = 0 to st.RowCount-1 do
> For j: = 0 to st.ColCount-1 do
Цей цикл в stDrawCell не потрібен. stDrawCell для кожного осередку викликається свій, при цьому координати осередку, для якої був викликаний stDrawCell можна дізнатися, прочитавши параметри ACol і ARow. Тобто всередині stDrawCell потрібно прикрашати тільки одну клітинку - з координатами [ACol; ARow]:
if (coloured = true) and (ACol = opt [i]) then # XA0; st.Canvas.Brush.Color: = clGreen
else st.Canvas.Brush.Color: = clWhite;
st.Canvas.FillRect (Rect);
st.Canvas.TextRect (Rect, Rect.Left, Rect.Top, st.Cells [ACol, ARow]);
навіщо цей дебільний подвійний цикл всередині події відтворення?
if (coloured = true) and (ACol = opt [i]) then # XA0; st.Canvas.Brush.Color: = clGreen
Всім велике спасибі))))