Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.08.2019, 01:08   #1
LeonDTym
 
Регистрация: 19.08.2019
Сообщений: 7
Лампочка Закрасить ячейку в Delphi (stringgrid)

Всем привет. Нужно закрасить ячейку с максимальным значением на диагоналях в stringgrid1. Я уже пытался закрасить нужную ячейку, но все безрезультатно. Суть проги это генерация матрицы, поиск максимального элемента и перенос этого элемента в центр второй. А закрашевание необходимо для удобства пользователя. Я приложу архив с прогой Матр.zip и сам код.

Код:
unit Unithghjjjjjjjjjjjjjjjjjjjjjjj;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, Buttons;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    StringGrid2: TStringGrid;
    Button3: TButton;
    BitBtn1: TBitBtn;
    Label1: TLabel;

    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure StringGrid2DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
     procedure StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);

  private
    { Private declarations }

  public
    { Public declarations }
  end;
   type Tmatr=array [1..50] of array [1..50] of real;
var
  Form1: TForm1;
  n:integer;
  matr:Tmatr;

implementation

{$R *.dfm}
  function findmax(var Matr: TMatr; var row, col: integer): real;
var i: integer; max: real;
begin
max := Matr[1,1]; row := 1; col := 1;
for i := 1 to n do
  begin
   //на главной диагонали
    if Matr[i, i] > max then
       begin
         max := Matr[i, i];
         row := i;
         col := i
        end;

   //на побочной диагонали
    if Matr[i, n-i+1] > max then
        begin
          max := Matr[i, n-i+1];
          row := i;
          col := n-i+1
         end;

  end;
findmax := max;

end;


     //трэш
    procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
var i: integer; max:real;
begin
  max := Matr[1,1]; Arow := 1; Acol := 1;
  for i := 1 to n do
      begin
    if Matr[i, i] > max then
       begin
         max := Matr[i, i];
         Arow := i;
         Acol := i
          end;

          begin
         if Matr[i, n-i+1] > max then
        begin
          max := Matr[i, n-i+1];
          Arow := i;
          Acol := n-i+1
         end;
             begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
        end;
        end;
        end;
end;
 //трэш




  //создание и вывод матрицы на экран
procedure TForm1.Button1Click(Sender: TObject);
  var i,j:integer;
begin
randomize;
repeat
n:=strtoint(edit1.text);
if not odd(n) then   //n должно быть нечетным
   begin
     edit1.text:=''; //Выводит текст если n нечетная
     edit1.Setfocus;
     exit;
   end;
until odd(n);
StringGrid1.RowCount := n;
StringGrid1.ColCount := n;
for i:=1  to n do
for j:=1 to n do
Matr[i,j]:=random*198-99;
for i:= 1 to n do
for j:=1 to n do
StringGrid1.Cells[j-1+1,i-1+1]:=FloatToStrF(matr[i,j],ffFixed,5,4);
 for i:=1 to n do begin
 StringGrid1.cells[0,i]:=''+inttostr(i);
 StringGrid1.cells[i,0]:=''+inttostr(i);
 StringGrid1.colCount:=n+1;
 StringGrid1.RowCount:=n+1;
 end;
  end;


//обмен элементов и вывод результата на экран
procedure TForm1.Button2Click(Sender: TObject);
 var  buf:real;
     i,j,row,col:integer;
begin
StringGrid2.RowCount := n;
StringGrid2.ColCount  := n;
buf := matr[n div 2 + 1, n div 2 + 1];
matr[n div 2 + 1, n div 2 + 1] := findmax(matr,row,col);
matr[row, col] := buf;
for i:= 1 to n do
for j:=1 to n do
StringGrid2.Cells[j-1+1,i-1+1]:=FloatToStrF(matr[i,j],ffFixed,5,4);
for i:=1 to n do begin
 StringGrid2.cells[0,i]:=''+inttostr(i);
 StringGrid2.cells[i,0]:=''+inttostr(i);
 StringGrid2.colCount:=n+1;
 StringGrid2.RowCount:=n+1;
end;
 end;


//Окрашивание центра второй матрицы
   procedure TForm1.StringGrid2DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
begin
  if ((ACol= n div 2+1)and(ARow= n div 2+1)) then
  begin
  StringGrid2.Canvas.Brush.Color:=clRed;
  StringGrid2.Canvas.FillRect(Rect);
  StringGrid2.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid2.Cells[Acol,Arow]);
   end;
end;

//Очистка данных
procedure TForm1.Button3Click(Sender: TObject);
 var i: integer;
begin
    Edit1.clear;
with StringGrid1  do
  for i:=0 to ColCount-1 do
    Cols[i].Clear;
with StringGrid2  do
  for i:=0 to ColCount-1 do
    Cols[i].Clear;

end;


end.
______________________
Форматируйте код и используйте тег [CODE] (кнопка [CODE] в форме сообщения) при вставке кода на форум. Подробнее в FAQ

Последний раз редактировалось Вадим Мошев; 19.08.2019 в 01:20.
LeonDTym вне форума Ответить с цитированием
Старый 19.08.2019, 08:27   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Вы делаете логическую ошибку.
Не надо искать максимум в процедуре закраски. Эта процедура вызывается для каждой ячейки матрицы отдельно. Поэтому Вы десятки раз впустую гоняете циклы.

а нужно сделать следующее.
1) заполнить матрицу случайными числами
2) найти максимум с помощью вашей функции findmax(matr,MaxRow,MaxCol);
3) полученные значения row и col, где находится максимальный элемент запомнить для дальнейшего использования (это можно сделать по разному.
например, в вашем случае можно использовать глобальные переменные (или переменные формы)
4) в процедуре procedure TForm1.StringGrid1DrawCell(Sender: TObject;
ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
если ACol, Arow совпадают с запомненными переменными, адресом максимального элемента, то закрасить ячейку.

всё.

p.s. можно не заводить глобальные переменные, а прямо в гриде сохранять признак того, что эта ячейка содержит максимальное значение - см. метод Objects : StringGrid1.Objects[MaxCol, MaxRow]
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.08.2019, 12:09   #3
LeonDTym
 
Регистрация: 19.08.2019
Сообщений: 7
Радость Большое спасибо

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Вы делаете логическую ошибку.
Не надо искать максимум в процедуре закраски. Эта процедура вызывается для каждой ячейки матрицы отдельно. Поэтому Вы десятки раз впустую гоняете циклы.

а нужно сделать следующее.
1) заполнить матрицу случайными числами
2) найти максимум с помощью вашей функции findmax(matr,MaxRow,MaxCol);
3) полученные значения row и col, где находится максимальный элемент запомнить для дальнейшего использования (это можно сделать по разному.
например, в вашем случае можно использовать глобальные переменные (или переменные формы)
4) в процедуре procedure TForm1.StringGrid1DrawCell(Sender: TObject;
ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
если ACol, Arow совпадают с запомненными переменными, адресом максимального элемента, то закрасить ячейку.

всё.

p.s. можно не заводить глобальные переменные, а прямо в гриде сохранять признак того, что эта ячейка содержит максимальное значение - см. метод Objects : StringGrid1.Objects[MaxCol, MaxRow]
Большое вам спасибо за объяснение. Я изначально понимал где ошибся, но нужен был чей-нибудь совет. Оказалось все намного проще
Код:
//Окрашивание макс. зн. в первой матрице
   procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
 var  row,col:integer;
begin
   findmax(matr,row,col);
  if ((ACol= col)and(ARow= row)) then
  begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
  StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
   end;
end;
LeonDTym вне форума Ответить с цитированием
Старый 19.08.2019, 13:02   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от LeonDTym Посмотреть сообщение
Оказалось все намного проще
НЕТ!!!!!

Вы опять повторяете одну и ту же ошибку!!!


Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Эта процедура вызывается для каждой ячейки матрицы отдельно. Поэтому Вы десятки раз впустую гоняете циклы.
Что Вам мешает сделать так:

Код:
.....
   type Tmatr=array [1..50] of array [1..50] of real;
var
  Form1: TForm1;
  n:integer;
  matr:Tmatr;
  MaxCol, MaxRow : integer;

.....
procedure TForm1.Button1Click(Sender: TObject);
  var i,j:integer;
begin
randomize;
repeat
n:=strtoint(edit1.text);
if not odd(n) then   //n должно быть нечетным
   begin
     edit1.text:=''; //Выводит текст если n нечетная
     edit1.Setfocus;
     exit;
   end;
until odd(n);
StringGrid1.RowCount := n;
StringGrid1.ColCount := n;
for i:=1  to n do
    for j:=1 to n do
        matr[i,j]:=random*198-99;

findmax(matr,MaxRow,MaxCol);

 StringGrid1.ColCount:=n+1;
 StringGrid1.RowCount:=n+1;

for i:= 1 to n do
for j:=1 to n do
StringGrid1.Cells[j-1+1,i-1+1]:=FloatToStrF(matr[i,j],ffFixed,5,4);
 for i:=1 to n do begin
   StringGrid1.cells[0,i]:=''+inttostr(i);
   StringGrid1.cells[i,0]:=''+inttostr(i);
 end;



  end;


//Окрашивание макс. зн. в первой матрице
   procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
 var  row,col:integer;
begin
  if ((ACol= MaxCol)and(ARow= MaxRow)) then
  begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
  StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
   end;
end;
и обратите внимание на выделенным зелённым - не надо в цикле присваивать одно и то же значение N раз!!!

Последний раз редактировалось Serge_Bliznykov; 19.08.2019 в 13:06.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.08.2019, 13:46   #5
LeonDTym
 
Регистрация: 19.08.2019
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
НЕТ!!!!!

Вы опять повторяете одну и ту же ошибку!!!




Что Вам мешает сделать так:

Код:
.....
   type Tmatr=array [1..50] of array [1..50] of real;
var
  Form1: TForm1;
  n:integer;
  matr:Tmatr;
  MaxCol, MaxRow : integer;

.....
procedure TForm1.Button1Click(Sender: TObject);
  var i,j:integer;
begin
randomize;
repeat
n:=strtoint(edit1.text);
if not odd(n) then   //n должно быть нечетным
   begin
     edit1.text:=''; //Выводит текст если n нечетная
     edit1.Setfocus;
     exit;
   end;
until odd(n);
StringGrid1.RowCount := n;
StringGrid1.ColCount := n;
for i:=1  to n do
    for j:=1 to n do
        matr[i,j]:=random*198-99;

findmax(matr,MaxRow,MaxCol);

 StringGrid1.ColCount:=n+1;
 StringGrid1.RowCount:=n+1;

for i:= 1 to n do
for j:=1 to n do
StringGrid1.Cells[j-1+1,i-1+1]:=FloatToStrF(matr[i,j],ffFixed,5,4);
 for i:=1 to n do begin
   StringGrid1.cells[0,i]:=''+inttostr(i);
   StringGrid1.cells[i,0]:=''+inttostr(i);
 end;



  end;


//Окрашивание макс. зн. в первой матрице
   procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
 var  row,col:integer;
begin
  if ((ACol= MaxCol)and(ARow= MaxRow)) then
  begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
  StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
   end;
end;
и обратите внимание на выделенным зелённым - не надо в цикле присваивать одно и то же значение N раз!!!
A я понял спасибо, что заметили
Код:
StringGrid1.ColCount:=n+1; StringGrid1.RowCount:=n+1;
И ещё когда вывожу
Код:
MaxCol, MaxRow : integer;
как глобальную переменную окрашивается ещё и первая клетка
Изображения
Тип файла: jpg Без имени.jpg (60.5 Кб, 96 просмотров)
LeonDTym вне форума Ответить с цитированием
Старый 19.08.2019, 13:50   #6
LeonDTym
 
Регистрация: 19.08.2019
Сообщений: 7
По умолчанию

А если оставить так то все нормально
Код:
procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
 var  row,col:integer;
begin
   findmax(matr,row,col);
  if ((ACol= col)and(ARow= row)) then
  begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
  StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
   end;
end;
Изображения
Тип файла: jpg Без имени1.jpg (60.9 Кб, 88 просмотров)
LeonDTym вне форума Ответить с цитированием
Старый 19.08.2019, 22:06   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от LeonDTym Посмотреть сообщение
как глобальную переменную окрашивается ещё и первая клетка
Выложите архив с проектом.

предположу, что первый раз грид закрашивается ещё до того, как нажали кнопку заполнения.

бороться с этим легко:

вариант 1.
добавьте событие на создание формы OnCreate
и там напишите
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
   MaxCol := -1;
   MaxRow := -1;
end;
ИЛИ
вариант 2.
так измените процедуру прорисовки
Код:
//Окрашивание макс. зн. в первой матрице
   procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
 var  row,col:integer;
begin
  if (MaxCol =0) or (MaxRow=0) then Exit;

  if ((ACol= MaxCol)and(ARow= MaxRow)) then
  begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
  StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
   end;
end;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 20.08.2019, 16:49   #8
LeonDTym
 
Регистрация: 19.08.2019
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Выложите архив с проектом.

предположу, что первый раз грид закрашивается ещё до того, как нажали кнопку заполнения.

бороться с этим легко:

вариант 1.
добавьте событие на создание формы OnCreate
и там напишите
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
   MaxCol := -1;
   MaxRow := -1;
end;
ИЛИ
вариант 2.
так измените процедуру прорисовки
Код:
//Окрашивание макс. зн. в первой матрице
   procedure TForm1.StringGrid1DrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
 var  row,col:integer;
begin
  if (MaxCol =0) or (MaxRow=0) then Exit;

  if ((ACol= MaxCol)and(ARow= MaxRow)) then
  begin
  StringGrid1.Canvas.Brush.Color:=clRed;
  StringGrid1.Canvas.FillRect(Rect);
  StringGrid1.Canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[Acol,Arow]);
   end;
end;
Сделал второй вариант. Теперь всё нормально, ещё раз спасибо.
LeonDTym вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не получается закрасить ячейку StringGrid с++ Builder Mat Bourn Помощь студентам 13 16.04.2019 13:46
Закрасить ячейку DBGrid по нажатию на кнопку dimok5 C++ Builder 3 24.03.2017 09:02
Как закрасить активную ячейку StringGrid demiancz Общие вопросы Delphi 1 05.05.2013 16:51
Как закрасить в WORD ячейку не полностью chilist Microsoft Office Word 3 24.03.2011 11:55
Задача StringGrid, требуется закрасить ячейку по координатам Mir@cle Помощь студентам 0 13.12.2010 19:50