На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Визуализация уровня данных
    Здравствуйте!
    Заранее оговорюсь - я не программист, я только учусь.
    Стояла задача визуализировать некоторую матрицу данных (или поток).
    Для определения матрицы данных использовалась консоль (в рамках получения цифр этого было достаточно).
    А вот для визуализации консоли оказалось недостаточно.
    16 цветов (симпатично, но не информативно)

    Прикреплённый файлПрикреплённый файлCON_1.png (14,18 Кбайт, скачиваний: 409)

    Может кто подскажет как получить чёрное поле с данными матрицы 100 х 2000, в которой значения изменяются от 0 до 100, каждое значение это ячейка на 2 символа, а цвет ячейки это интенсивность белого цвета, которое соответствует значению матрицы.
      Создайте битмап, в нужных местах рисуйте прямоугольники соответствующего цвета

      ExpandedWrap disabled
            l := value * 255 div 100;
            bmp.Canvas.Brush.Color := RGB(l,l,l);
            bmp.Canvas.FillRect(...)
        Цитата MBo @
        Создайте битмап

        Спасибо за направление, буду изучать поскольку совершенно не знаком с формами, т.к. по специальности я физик
          Цитата ivan1234 @
          Создайте битмап

          Упёрся в следующую проблему - как из консоли, получив промежуточное значения расчёта, открыть форму, вывести на форме значение этого промежуточного результата в виде градации цвета и опять вернуться к расчёту т.д.
            Нашёл такой пример для начинающих, немного переделал под свои нужды, то что вижу на экране для начала вполне устраивает зрительно:

            ExpandedWrap disabled
              unit unit2;
               
              interface
               
              uses
                Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                Dialogs, StdCtrls;
               
              type
                TForm1 = class(TForm)
                  procedure FormCreate(Sender: TObject);
                  procedure FormPaint(Sender: TObject);
                private
                  { Private declarations }
                public
                  { Public declarations }
                end;
               
              type
                TFigure = class
                private
                  {Private declarations }
                  FX,FY:integer; // поля координаты
                  FColor:integer; // поле цвет
                  Fn:integer; // поле длина ребра
                public
                  { Public declarations }
                  procedure Paint; virtual; abstract;
                  procedure SetColor(c:integer);
                  procedure Coordinates(X,Y:integer);
                  property Color : integer read FColor write SetColor; // Свойство цвет
                  property n : integer read Fn write Fn; // Свойство ребро
                  property X : integer read FX write FX; // Свойство координата X
                  property Y : integer read FY write FY; // Свойство координата Y
                end;
               
               
              type
                TSquare = class(TFigure)
                private
                  { Private declarations }
                public
                  { Public declarations }
                  procedure Paint();override; {переопределяем базовый метод}
                end;
               
              type
                TMyObjects = class
                private
                  { Private declarations }
                  ArrObj: Array of TFigure; {массив, элементами которого являются объекты нашего типа TSquare}
                public
                  { Public declarations }
                  procedure AddFigure(X,Y,Color,n:integer);
                  procedure RePaint();
                  procedure RePaint2();
                end;
               
               
              var
                Form1: TForm1;
                MyObjects:TMyObjects;
                v, g: Byte;
               
              implementation
               
              {$R *.dfm}
               
              { TFigure }
              procedure TFigure.Coordinates(X, Y: integer);
                begin
                  FX:=X;
                  FY:=Y;
                end;
               
              procedure TFigure.SetColor(c: integer);
                begin
                  FColor:=c;
                end;
               
              { TSquare }
              procedure TSquare.Paint;
                begin
                  Form1.Canvas.Brush.Color := FColor;
                  Form1.Canvas.Rectangle(X,Y,X+n,Y+n); //рисуем квадрат
                end;
               
              { TMyObjects }
              procedure TMyObjects.AddFigure(X, Y, Color,n: integer);
              var
                i:integer;
                b:byte;
                begin
                  b := 0;
                  for i:=0 to Length(ArrObj)-1 do
                    if ArrObj[i] = nil then
                      begin
                        b := 1;
                        Break;
                      end;
                  if b = 0 then //нет свободных, увеличим массив
                    begin
                      SetLength(ArrObj, Length(ArrObj)+1);
                      i := Length(ArrObj)-1;
                    end;
                  ArrObj[i]:=TSquare.Create;
                  ArrObj[i].Coordinates(x,y);
                  ArrObj[i].SetColor(Color);
                  ArrObj[i].n:=n;
              end;
               
              procedure TMyObjects.RePaint;
              var
                i:integer;
                begin
                  for i:=0 to Length(ArrObj)-1 do
                    if ArrObj[i] <> nil then
                      ArrObj[i].Paint;
                end;
               
              procedure TMyObjects.RePaint2;
              var
                i:integer;
                Color:integer;
                begin
                  i:= 10;
                  Color:= RGB(Random(255),Random(255),Random(255));
                  MyObjects.AddFigure(g*10,v*10,Color,i);
                  MyObjects.RePaint;
                end;
               
              procedure TForm1.FormPaint(Sender: TObject);
                begin
                  for v:=0 to 63 do
                    for g:=0 to 63 do
                      MyObjects.RePaint2;
                end;
               
              procedure TForm1.FormCreate(Sender: TObject);
                begin
                  MyObjects := TMyObjects.Create;
                end;
               
              end.


            ... Но почему так медленно??? С такой скоростью просто в мусорку.
            Может есть какой нибудь способ побороть этот недостаток?
              Процедура AddFigure реализована плохо. Расширение массива на единицу - неправильный подход, медленный и
              может жрать память (в зависимости от версии Delphi и соотв. менеджера памяти)

              А вообще я не вижу смысла во введении всех этих объектов. Никакого полезного функционала, по крайней мере в текущей реализации, они в себе не содержат.

              Так что лучше использовать то, что я посоветовал: матрица данных у Вас уже есть, в ней содержится вся необходимая информация. По значению элемента считаете цвет, рисуете прямоугольник. Лишние прокладки - нафиг.
              Сообщение отредактировано: MBo -
                Цитата MBo @
                Процедура AddFigure реализована плохо

                )за что купил, за то продал
                попробовал ваш совет:
                ExpandedWrap disabled
                  procedure TForm1.FormPaint(Sender: TObject);
                    begin
                      for v:=0 to 12000 do
                        for g:=0 to 63 do
                          with Form1.Canvas do
                            begin
                              s:= Random(255);
                              Pen.Color:=RGB(s,s,s);
                              Brush.Color:=RGB(s,s,s);
                              Rectangle(10*g, 10*v, 10*g+10, 10*v+10);
                            end;
                    end;

                работает значительно быстрее - просто замечательно
                Но по ходу изучения возникло ещё 2 вопроса:
                1. как скролить такой большой массив как в примере?
                2. как к скролу дополнительно добавить поток строк?
                  Цитата ivan1234 @
                  1. как скролить такой большой массив как в примере?
                  2. как к скролу дополнительно добавить поток строк?

                  Я бы выбрал визуальный компонент типа Grid и заполнял ячейки цветом. Тогда и скролить было бы можно. Осталось найти такой компонент
                    >Осталось найти такой компонент
                    Так сам грид всё умеет. Пример


                    >как скролить такой большой массив как в примере?
                    Отрисовать матрицу в битмап, битмап на PaintBox, лежащем на ScrollBox.
                    Если размеры слишком велики, то битмап вообще можно не создавать (размеры ограничены, памяти нужно много),
                    а рассчитывать часть матрицы, помещающуюся в скроллируемое окно (ScrollBox), и только эту часть выводить.



                    >как к скролу дополнительно добавить поток строк?
                    Что это означает??
                      Цитата MBo @
                      Отрисовать матрицу в битмап, битмап на PaintBox, лежащем на ScrollBox.

                      С битмапом пока не разобрался, если я правильно понял необходимо заранее создать 256 картинок с градацией серого, где то его хранить, если на диске, то боюсь опять возникнут проблемы со скоростью, если создавать в процессе запуска программы, то как это правильно реализовать пока не знаю, потому как ООП для меня пока как для чайника))

                      Цитата MBo @
                      >как к скролу дополнительно добавить поток строк?
                      Что это означает??

                      всё очень просто: (в общем смысле) какой либо процесс имеет свой спектральный состав - это строка частот с различными амплитудами... но процессы очень редко бывают стабильными во времени, а на осциллограмме мы видим только мгновенное состояние спектра. Получив поток таких строк позволит более детально изучить изменение спектра во времени, тем более что время изменения спектра ничтожно мало. Т.е. при постоянном анализе на поле формы хотелось бы увидеть постоянно меняющуюся в реальном времени матрицу спектра. В console это прекрасно реализуется, но к сожалению только цифрами.
                      Сообщение отредактировано: ivan1234 -
                        >если я правильно понял необходимо заранее создать 256 картинок с градацией серого,
                        Видимо, неправильно.
                        ООП тут ни при чём.

                        >изменение спектра во времени
                        Посмотрите, что такое сонограмма
                          Цитата MBo @
                          Видимо, неправильно.

                          может посоветуете литературу в которой хорошо разжёвано про Bitmap?
                          Цитата MBo @
                          Посмотрите, что такое сонограмма

                          здесь я совсем не понял, как это относится к моему вопросу, ну существует такой термин в медицине, возможно что то отдалённо похожее я хочу увидеть у себя на экране... и что? меня интересует как это реализовать, а не как это назвать
                            https://ru.wikipedia.org/wiki/Спектрограмма

                            Вопрос про скролл я сначала понял как скроллирование окна, поскольку размер 12000 указан.

                            Вам же, похоже, нужно, чтобы просто бежали вверх или вниз строки с информацией.
                            Достаточно иметь массив с таким количеством строк, чтобы помещалось на экране, расширять его не надо (если не требуется сохранять всё).
                            После приёма новой строки можно сдвигать данные в массиве на одну строку вверх, новую дописывать в конец, потом выводить содержимое массива.
                            Сообщение отредактировано: MBo -
                              Цитата MBo @
                              Вопрос про скролл я сначала понял как скроллирование окна, поскольку размер 12000 указан.

                              именно так и спрашивалось в 1 пункте, а 2 пункт это одновременная реализация скрола и бегущая строка, по крайней мере так реализовано в консоли.

                              Возможно то что я хочу получить в конечном счёте не реализуемо на форме, тогда перед собой я поставлю скорее всего другую задачу и приду к решению типа:
                              Цитата MBo @
                              Достаточно иметь массив с таким количеством строк, чтобы помещалось на экране, расширять его не надо (если не требуется сохранять всё).
                              После приёма новой строки можно сдвигать данные в массиве на одну строку вверх, новую дописывать в конец, потом выводить содержимое массива.


                              Что касаемо Bitmap, то в инете про него от 2 предложений до 2 страниц (для профессионалов), я же не профессионал и мне этих 2 страниц мало, тем более что всё описание Bitmap отирается на классы, методы и свойства, а ООП я только начал изучать)

                              Добавлено

                              я работаю в области металловедения (структуры, состояния, характеристики, свойства и тд), а привёл простейший пример известный даже школьнику чтобы было понятно что мне нужно получить на выходе, а СПЕКТРОГРАММА в определении википедии лишь частный случай возможного применения такого метода
                              Сообщение отредактировано: ivan1234 -
                                Цитата ^D^ima @
                                Я бы выбрал визуальный компонент типа Grid

                                Цитата MBo @
                                Так сам грид всё умеет


                                Попробовал этот вариант. Всё заполняет, есть скрол, но:
                                1. На вскидку обращение к ячейкам таблицы работает в 2 раза медленнее чем обращение к координатам точки
                                2. Встроенная сетка несколько мешает восприятие зрительной информации (как её убрать сетку не знаю, потому как чайник)
                                3. Скол работает как скрол строки, а не всей таблицы и в месте фокуса затирает значение
                                4. Когда доходит до последней строчки окна начинает скролить таблицу, но изменяет размер ячеек по высоте и затирает информацию в невидимых строках

                                В общем исходя их выше сказанного, наилучшим способом оказалось обращение к координатам пикселя, хотелось только добавить туда работоспособный скрол.
                                Был бы очень благодарен за кусок кода, который позволил бы это реализовать.
                                  Цитата ivan1234 @
                                  Упёрся в следующую проблему - как из консоли, получив промежуточное значения расчёта, открыть форму, вывести на форме значение этого промежуточного результата в виде градации цвета и опять вернуться к расчёту т.д.

                                  1) Отдельным GUI приложением, связь держать через любой способ - STDIN, сокеты, сообщения, маппинг памяти (имхо для озвученных целей - самое простое)
                                  2) Изначально сделать GUI приложение, добавить консоль через AttachConsole

                                  С отображением: помимо грида, можно попробовать с listview, хотя я бы, наверно, сделал paintbox + собственная отрисовка
                                  Сообщение отредактировано: Fr0sT -
                                    Цитата Fr0sT @
                                    С отображением: помимо грида, можно попробовать с listview, хотя я бы, наверно, сделал paintbox + собственная отрисовка


                                    Начал пробовать этот вариант, и при создании первой таблицы выяснилось что для большого количества строк (8000-12000)это очень трудоёмкий процесс, поскольку каждую строку необходимо вносить вручную, можно конечно и программно, но тогда скорость заполнения онлайн значительно снижается.

                                    Попробовал вернуться к StringGrid1DrawCell, оказалось, что при правильной настройке параметров таблицы многие проблемы описанные ранее вообще отпали, но пока осталась самая существенная - если матрица значений (цветов) больше окна на форме то при скроле таблицы в моём варианте обновляются цвета ячеек. Есть ли возможность это как то побороть. Допускаю что просто код у меня совершенно кривой, или просто событие OnDrawCell невозможно остановить после первого заполнения таблицы?

                                    Кусок моего кода, которым заполняется таблица:

                                    ExpandedWrap disabled
                                      procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
                                                                            Rect: TRect; State: TGridDrawState);
                                        begin
                                          with StringGrid1 do
                                            begin
                                              s:= Random(255);
                                              Canvas.Brush.Color:=RGB(s,s,s);
                                              Canvas.FillRect(CellRect(ACol, ARow));
                                            end;
                                        end;
                                       
                                      procedure TForm1.FormPaint(Sender: TObject);
                                        begin
                                          for ARow:=0 to 63 do
                                            for ACol:=0 to 63 do
                                              StringGrid1DrawCell(Sender,ACol,ARow,Rect,State);
                                        end;
                                      >при скроле таблицы в моём варианте обновляются цвета ячеек
                                      Естественно, ведь они при перерисовке заполняются случайным серым цветом
                                      ExpandedWrap disabled
                                        s:= Random(255);
                                        Canvas.Brush.Color:=RGB(s,s,s);


                                      А вот вызывать StringGrid1DrawCell (из Paint) не нужно вообще - событие само возникнет при необходимости перерисовки видимых ячеек, тогда и обработчик вызовется.
                                        Цитата MBo @
                                        Естественно, ведь они при перерисовке заполняются случайным серым цветом

                                        получается так? запускаю программу, программа выполняет главный и вложенный цикл, заполняет таблицу случайным образом и останавливается в конце главного цикла, но... когда я хочу просмотреть ту часть таблицы которая не влезла в окно, эта часть таблицы не статична, а перезаполняется опять новыми случайными числами.... те я уже буду видеть не те начальные данные, а уже изменённые - пока я не пойму как это происходит, и самое главное для чего нужно продолжать закончившийся цикл??
                                        Цитата MBo @
                                        событие само возникнет при необходимости перерисовки видимых ячеек

                                        В том то и дело что мне не нужно перерисовывать первоначально заполненную таблицу, мне нужно её просмотреть, выбрать значимые участки, сделать допустим PS и тд. те в конце главного цикла остановить работу обработчика.

                                        ЗЫ: понятно что в реальной ситуации вместо генератора в таблицу заносятся реальные значения реальных датчиков, хочу сказать что реализация такого визуального представления даже в кусочном виде позволяет сделать значительный скачок в анализе результатов. Очень жаль что в настоящий момент не получается увидеть сразу всю картину процесса целиком)
                                        Сообщение отредактировано: ivan1234 -
                                          Цитата MBo @
                                          А вот вызывать StringGrid1DrawCell (из Paint) не нужно вообще

                                          Проверил - если я правильно понял, циклы в моём коде вообще не работают просто по циклам автоматически таблица заполняется полностью вся, размеры которой указаны в параметрах StringGrid. Но остаётся вопрос - как например заполнить таблицу наполовину, и как её зафиксировать?
                                            Ваша задача - вместо Random обеспечить значение, соответствующее индексам ACol, ARow.
                                              Цитата MBo @
                                              Ваша задача - вместо Random обеспечить значение, соответствующее индексам ACol, ARow

                                              вроде всё работает, но тогда получается что при каждом скроле вся таблица и соответственно весь код по заполнению полностью повторяется и окно полностью перерисовывается начиная с величины сдвига (те таблица не хранится в памяти и не сдвигается окно по таблице). Я конечно проверю, но скорее всего большая матрица будет двигаться по окну как шторка. И второе - поток в этом случае исключается полностью, потому как между вводом данных и выводом результатов на экран есть ещё целая куча математики, которая и так существенно тормозит код.
                                                Цитата Fr0sT @
                                                можно попробовать с listview

                                                Как и всегда оказалось, что если у кого то не получается что то сделать (кто то это конечно же я) - это совершенно не означает что это невозможно осуществить в принципе, просто на тот период у этого "кто то" недостаточно знаний.
                                                Перекопав огромное количество примеров оказалось, что listview прекрасно справляется с поставленной задачей, заполняет поле мгновенно, да и скол присутствует в различных видах, правда несколько тормозит при прокрутке всего окна, но на этом этапе для меня этого достаточно.
                                                Всем кто принял участие огромное спасибо!
                                                Проект который у меня получился выложен здесь:
                                                ExpandedWrap disabled
                                                  unit Unit_1;
                                                  interface
                                                  uses
                                                    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                                                    Dialogs, StdCtrls, ExtCtrls, ComCtrls;
                                                  type
                                                    TForm1 = class(TForm)
                                                      ListView1: TListView;
                                                      procedure FormCreate(Sender: TObject);
                                                      procedure ListView1Data(Sender: TObject; Item: TListItem);
                                                   
                                                      procedure ListView1CustomDrawItem(Sender: TCustomListView;
                                                                Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
                                                      procedure ListView1CustomDrawSubItem(Sender: TCustomListView;
                                                                Item: TListItem; SubItem: Integer; State: TCustomDrawState;
                                                                var DefaultDraw: Boolean);
                                                   
                                                    private
                                                      { Private declarations }
                                                    public
                                                      { Public declarations }
                                                    end;
                                                   
                                                  var
                                                    Form1: TForm1;
                                                   
                                                  implementation
                                                   
                                                  {$R *.dfm}
                                                   
                                                  uses
                                                    Unit_2;
                                                   
                                                  type
                                                    TColorData=record
                                                  end;
                                                   
                                                  var
                                                    arr: TSimpleArr;
                                                    s: Word;
                                                   
                                                  procedure TForm1.FormCreate(Sender: TObject);
                                                  var
                                                    lc: TListColumn;
                                                    j: integer;
                                                      begin
                                                        MatrData(arr);
                                                        Listview1.OwnerData:=True;
                                                        ListView1.ViewStyle:=vsReport;
                                                        for j:=0 to 10 do
                                                          begin
                                                            lc:=ListView1.Columns.Add;
                                                            lc.Caption:=inttostr(j-1);
                                                            lc.Width:=42;
                                                          end;
                                                        ListView1.RowSelect:=true;
                                                        ListView1.Items.Count:=Length(arr);
                                                        Caption:=IntToStr(Length(arr));
                                                      end;
                                                   
                                                   
                                                  procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
                                                            Item: TListItem; State: TCustomDrawState;
                                                            var DefaultDraw: Boolean);
                                                   
                                                      begin
                                                        Sender.Canvas.Brush.Color:=RGB(255,255,255);
                                                      end;
                                                   
                                                  procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
                                                            Item: TListItem; SubItem: Integer; State: TCustomDrawState;
                                                            var DefaultDraw: Boolean);
                                                   
                                                      begin
                                                        Sender.Canvas.Brush.Color:=RGB(s,s,s);;
                                                      end;
                                                   
                                                  procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
                                                  var
                                                    n, j: integer;
                                                    begin
                                                      n:=10;
                                                      item.Caption:=arr[item.Index,0].caption;
                                                      for j:= 0 to n-1 do
                                                        begin
                                                          item.SubItems.Add(IntToStr(arr[item.Index,j].data));
                                                          s:= arr[item.Index,j].data;
                                                        end;
                                                    end;
                                                  end.

                                                и
                                                ExpandedWrap disabled
                                                  unit Unit_2;
                                                   
                                                  interface
                                                  uses SysUtils;
                                                    type
                                                      TColor =record
                                                        caption:string;
                                                        data:integer;
                                                      end;
                                                      TSimpleArr = array of array of TColor;
                                                      procedure MatrData(var arr:TSimpleArr);
                                                   
                                                  implementation
                                                   
                                                  procedure MatrData(var arr:TSimpleArr);
                                                  var
                                                    k, n, i, j: integer;
                                                   
                                                      begin
                                                        k:=12000;
                                                        n:=10;
                                                        SetLength(arr,k,n);
                                                        for i := 0 to k-1 do
                                                          for j:= 0 to n-1 do
                                                            begin
                                                              arr[i,j].caption:=inttostr(i);
                                                              arr[i,j].data:=i*j;
                                                            end;
                                                      end;
                                                   
                                                  end.
                                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                0 пользователей:


                                                Рейтинг@Mail.ru
                                                [ Script execution time: 0,0697 ]   [ 18 queries used ]   [ Generated: 25.04.24, 17:13 GMT ]