Форум: "Начинающим";
Текущий архив: 2009.05.17;
Скачать: [xml.tar.bz2];
Внизрисование компонент Найти похожие ветки
← →
mnj (2009-04-01 17:40) [0]Доброго дня.
Помогите, пожалуйста с такой штукой:
Нужно нарисовать матрицу из панелек
(цвет - индикация величины, пока не сделано)
по значениям из динамического массива
Это:
SetLength(Blocks,NumberOfRows,NumberOfBlocks);
for I:= 1 to NumberOfRows do
begin
for K:= 1 to NumberOfBlocks do
begin
Blocks[i-1,k-1]:= TPanel.Create(Self);
with Blocks[i-1,k-1] do
begin
Parent:= pnModel;
Left:= 20+(K-1)*15;
Top:= 20+(I-1)*20;
Width:= 15;
Height:= 20;
Color:= clBlue;
Tag:= I*10+K;
end; {of with}
end;
end;
рисует медленно и с мерцанием. Можно ли сделать это быстрее и без мерцания?
И второй вопрос - как обрабатывать события компонентов, созданных во время выполнения, как в моем случае?
← →
Игорь Шевченко © (2009-04-01 18:40) [1]
> Можно ли сделать это быстрее и без мерцания?
Можно.
> И второй вопрос - как обрабатывать события компонентов,
> созданных во время выполнения, как в моем случае?
Также, как обычно.
Рисовать можно например так:
Положить на форму PaintBox, на его событии OnPaint нарисовать нужное количество квадратиков.
В качестве тупого примера рисуется 1024 (32х32) квадратика
procedure TfMain.DrawMap(const Map: TMemoryMap; PaintBox: TPaintBox);
var
Column : Integer;
GridHeight: Integer;
GridWidth : Integer;
Row : Integer;
I : Integer;
BrushNew, BrushOld : HBRUSH;
begin
GridHeight := PaintBox.Height div 32;
GridWidth := PaintBox.Width div 32;
for I := 0 to 1023 do begin
Row := I div 32;
Column := I mod 32;
BrushNew := CreateSolidBrush(TMemory.MapEntryColor(Map[I]));
BrushOld := SelectObject(PaintBox.Canvas.Handle, BrushNew);
Rectangle(PaintBox.Canvas.Handle, GridWidth*Column, GridHeight*Row,
GridWidth*(Column+1), GridHeight*(Row+1));
SelectObject(PaintBox.Canvas.Handle, BrushOld);
DeleteObject(BrushNew);
end;
end;
Получается сеточка из разноцветных квадратиков.
← →
mnj (2009-04-01 20:48) [2]спасибо за совет, но дело в том, что мне нужно иметь каждую клеточку отдельным объектом, свойства которого меняются в заданной зависимости по клику мыши, например - цвет, По-моему, PaintBox не подходит для этого.
← →
Игорь Шевченко © (2009-04-01 21:00) [3]mnj (01.04.09 20:48) [2]
Очень даже подходит для этого PaintBox, потому как он только средство отображения (ну и клик мыши тоже воспринимает). А объект с меняющимися свойствами - он отдельный и сам по себе, хотя бы и в массиве.
Если обратить внимание, то в процедуре рисования отображается состояние (цвет, кстати) именно объектов, другое дело, что объекты простые, но сложными быть им никто не мешает.
Мышкой щелкать тоже, кстати, просто
procedure TfMain.PaintBoxWholeMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
EntryIndex, EntryX, EntryY : Integer;
GridHeight: Integer;
GridWidth : Integer;
PaintBox : TPaintBox;
begin
PaintBox := Sender as TPaintBox;
if Button = mbLeft then begin
GridHeight := PaintBox.Height div 32;
GridWidth := PaintBox.Width div 32;
EntryX := (X div GridWidth);
EntryY := (Y div GridHeight);
EntryIndex := EntryY * 32 + EntryX;
SelectWholeMapEntry(EntryIndex);
end;
end;
Определили индекс объекта и делаем с ним, что хотим.
В моем случае (это карта вирутальной памяти процесса), в зависимости от состояния участка памяти в довольно крупном масштабе
(свободен, выделен, занят кодом, и т.п.), определяется его цвет, а при щелчке мышью конкретно этот участок отображается рядом более детально.
То есть, объекты налицо :)
← →
mnj (2009-04-01 21:33) [4]Спасибо, попробую.
← →
mnj (2009-04-02 00:24) [5]Это тоже все хорошо, я сделал вот так:
for I:= 1 to NumberOfRows do
begin
for K:= 1 to NumberOfBlocks do
begin
with pbModel.Canvas do
begin
X:= 20+(K-1)*10;
Y:= 20+(I-1)*20;
dX:= 15;
dY:= 20;
Pen.Style:= psSolid;
Brush.Style:= bsSolid;
Pen.Color:= clBlack;
Brush.Color:= clGreen;
Rectangle(X,Y,X+dX,Y+dY);
end
end
end;
Беда в том, что при перекрытии PaintBox каким-либо элементом, окном, например, картинка стирается. Как с этим бороться?
← →
Игорь Шевченко © (2009-04-02 01:01) [6]
> Это тоже все хорошо, я сделал вот так:
Надеюсь, это код процедуры PaintBoxPaint
← →
Amoeba © (2009-04-02 01:20) [7]
> Игорь Шевченко © (02.04.09 01:01) [6]
>
>
> > Это тоже все хорошо, я сделал вот так:
>
>
> Надеюсь, это код процедуры PaintBoxPaint
Судя по
> при перекрытии PaintBox каким-либо элементом, окном, например,
> картинка стирается
похоже на то, что надежда оказалась напрасной.
← →
Amoeba © (2009-04-02 01:34) [8]Как вариант, можно использовать DrawGrid и в нем раскрашивать ячейки. Я бы лично предпочел такой путь.
← →
Германн © (2009-04-02 02:11) [9]
> Amoeba © (02.04.09 01:34) [8]
>
> Как вариант, можно использовать DrawGrid и в нем раскрашивать
> ячейки. Я бы лично предпочел такой путь.
>
+1
Я когда-то в некоей задаче пошёл именно таким путём.
Правда кол-во строк и колонок было изначально фиксированно. И нужны были Fixed Rows & Cols.
← →
Игорь Шевченко © (2009-04-02 02:18) [10]Amoeba © (02.04.09 01:34) [8]
> Как вариант, можно использовать DrawGrid и в нем раскрашивать
> ячейки. Я бы лично предпочел такой путь.
Можно. Но в моем случае (карта виртуальной памяти процесса) проще раскрасить PaintBox 32x32. И кода меньше :)
← →
Германн © (2009-04-02 02:31) [11]
> Игорь Шевченко © (02.04.09 02:18) [10]
Я. конечно, уже многим надоел своими требованиями к вопросам, но ...
Без приведения в сабже "задачи", нет возможности дать "правильный ответ" на сабж, без включения телепатора.
А телепатор - вещь весьма мало предсказуемая.
← →
Игорь Шевченко © (2009-04-02 02:43) [12]Германн © (02.04.09 02:31) [11]
Это факт. Вот у автора вопроса есть уже выбор из двух вариантов.
← →
ЮЮ © (2009-04-02 08:32) [13]
> mnj (02.04.09 00:24) [5]
>
> Это тоже все хорошо, я сделал вот так:
> Беда в том, что при перекрытии PaintBox каким-либо элементом,
> окном, например, картинка стирается. Как с этим бороться?
>
Важно не только как, но и где, т.е. каком обработчике стоит этот код.
← →
mnj (2009-04-02 12:44) [14]Код стоит в обработчике открытия файла (стандартный диалог открытия файла, формат - текстовый). Задача - по условным цветовым кодам нарисовать модель геоэлектрического разреза, где каждый цвет обозначает определенную величину удельного электрического сопротивления. В геофизике при моделировании этот разрез разбивается на заданное число блоков и имеет вид матрицы MxN, где M - число блоков по горизонтали (профилю), N - число блоков по вертикали (в глубину). Каждому блоку присваивается свое значение удельного электрического сопротивления, обозначаемое кодом (0..f), таким образом, зона из блоков с одинаковым значением представляет собой геологическое тело в разрезе. Необходимо менять значения сопротивления чтобы создавать тела с другим сечением. Формат входного файла изобретен автором программы инверсии данных (т.е. расчета геоэлектрического поля в разрезе в зависимости от пространственного положения источника поля) и от него я и вынужден отталкиваться. Вместо конкретных значений он использует коды: 0 - значение сопротивления 1, 1 - значение 2, 2 - значение 3 и т.д. до f (предел - 16 значений). в файле разрез выглядит вот так:
000000000000000000000000000000000
000000000111111100000000000000000
000000001111111110000000000000000
000000011111111111000000000000000
000000111111111111100000000000000
000001111111111111110000000000000
111111111111111111111111111111111
111111111111111111111111111111111
В PaintBox нарисовать это несложно, но изображение затирается (см. выше). приведенный в [5] код и относится к варианту с PaintBox. Матрица из панелек, создаваемая runtime - слишком медленно[1]. Попробуем DrawGrid;
← →
mnj (2009-04-02 13:25) [15]Тогда еще возникает момент - как раскрасить отдельную ячейку DrawGrid?
← →
Amoeba © (2009-04-02 15:22) [16]
> mnj (02.04.09 13:25) [15]
>
> Тогда еще возникает момент - как раскрасить отдельную ячейку
> DrawGrid?
Кодом, написанным в OnDrawCell.
← →
mnj (2009-04-02 16:34) [17]Все равно - рисование через канву затирается, поэтому очень неудобро восстанавливать изображение.
Такой вариант:
SetLength(Blocks,NumberOfRows,NumberOfBlocks);
for I:= 1 to NumberOfRows do
begin
for K:= 1 to NumberOfBlocks do
begin
Blocks[i-1,k-1]:= TPanel.Create(Self);
Blocks[i-1,k-1].Hide; //непоказывать блок
with Blocks[i-1,k-1] do
begin
Parent:= pnModel;
Left:= 20+(K-1)*15;
Top:= 20+(I-1)*20;
Width:= 15;
Height:= 20;
Color:= clBlue;
Tag:= I*10+K;
end; {of with}
end;
end;
OldBlocks:= NumberOfBlocks;
OldRows:= NumberOfRows;
for I:= 1 to NumberOfRows do
begin
for K:= 1 to NumberOfBlocks do
begin
Blocks[i-1,k-1].Show;//теперь показывать
end;
end;
ускорил процесс и убрал мерцание. Изображение также сохраняется.
Но можно ли еще ускорить вывод панелек?
← →
Игорь Шевченко © (2009-04-03 01:28) [18]mnj (02.04.09 16:34) [17]
Было бы неплохо увидеть не только процедуру рисования, но и то место, откуда она вызывается. Иначе мы будем долго гадать, почему затирается и как ускорить
← →
Германн © (2009-04-03 02:00) [19]
> Игорь Шевченко © (03.04.09 01:28) [18]
И так ясно что сия процедура вызывается "не оттуда, откуда нужно".
Ясен перец - нужно читать книги.
А вот ссылки на статьи по этой теме я не знаю.
Может Амёба знает?
← →
mnj (2009-04-03 02:16) [20]Вот добил: прячу панель-контейнер, создаю в ней нужное количество панелек и показываю снова с готовым результатом.
pnModel.Hide; //прячем панель
if (OldBlocks > 0) and (OldRows > 0) then
begin
for I:= 1 to OldRows do
begin
for K:= 1 to OldBlocks do
Blocks[i-1,k-1].Free; //стираем, если было что
end;
end;
{-------------------------Рисование блоков-------------------------}
SetLength(Blocks,NumberOfRows,NumberOfBlocks);
for I:= 1 to NumberOfRows do
begin
for K:= 1 to NumberOfBlocks do
begin
Blocks[i-1,k-1]:= TPanel.Create(Self);
with Blocks[i-1,k-1] do
begin
Parent:= pnModel;//родительская панель-контейнер - спрятана, поэтому "рисование" происходит быстро и скрыто.
Left:= 20+(K-1)*(pnModel.Width-20) div (NumberOfBlocks+1);
Top:= 20+(I-1)*pnModel.Height div (NumberOfRows*2);
Width:= (pnModel.Width-20) div (NumberOfBlocks+1);
Height:= pnModel.Height div (NumberOfRows*2);
Color:= ColorTable[ResistivityMatrix[i-1,k-1]];
Tag:= I*10+K;
end; {of with}
end;
end;
OldBlocks:= NumberOfBlocks;
OldRows:= NumberOfRows;
pnModel.Show; //показываем все
3136 панелек рисовалось примерно 2 с (матрица 196х16), 1120 (80х14) штук - меньше секунды, 4536 штук (252х18) - примерно 5 с. Никакого затирания, естественно, и никакого мерцания.
Должен признаться, что хотел использовать шейп, но шейп не имеет фокуса ввода пользователя...
← →
Игорь Шевченко © (2009-04-03 02:25) [21]
> 4536 штук (252х18) - примерно 5 с.
Ради интереса запустил свой проект (который с PaintBox :)
2048 клеточек рисуются мгновенно (ну то есть, совсем мгновенно).
Помещаю поверх окна своей программы окна других программ, убираю - окном моей программы рисуется, опять же, мгновенно.
← →
MsGuns © (2009-04-03 09:05) [22]>Должен признаться, что хотел использовать шейп, но шейп не имеет фокуса ввода пользователя...
А фокус и не нужен, достаточно просто ловить мышиный клик и определять какой контрол под ней находится
← →
Jeer © (2009-04-03 15:38) [23]
> Игорь Шевченко © (03.04.09 02:25) [21]
>
>
> > 4536 штук (252х18) - примерно 5 с.
>
>
> Ради интереса запустил свой проект (который с PaintBox :
> )
> 2048 клеточек рисуются мгновенно (ну то есть, совсем мгновенно).
>
Отличный пример, Игорь.
Насчет прорисовки ( CPU 3 GHz ):
- 1024 рисуются за 9 ms
- 4096 * 38 ms
- 16 тыс за 135 ms
← →
mnj (2009-04-04 01:54) [24]Спасибо за помощь
← →
KilkennyCat © (2009-04-04 04:06) [25]
> Игорь Шевченко ©
Я бы все-таки сделал через буферный битмап, а потом bitblt - это гарантирует появление квадратиков всех сразу, если у кого-то вдруг 286 проц или видеодрайвер не установлен :)
← →
mnj (2009-04-04 15:26) [26]>KilkennyCat © (04.04.09 04:06) [25]
>> Игорь Шевченко ©
>Я бы все-таки сделал через буферный битмап, а потом bitblt - это >гарантирует появление квадратиков всех сразу, если у кого-то вдруг 286 >проц или видеодрайвер не установлен :)
А где это - bitblt? Я не нашел такой.
← →
Palladin © (2009-04-04 15:51) [27]
> А где это - bitblt? Я не нашел такой.
даже в гугле?
← →
Игорь Шевченко © (2009-04-04 19:11) [28]KilkennyCat © (04.04.09 04:06) [25]
Овчинка выделки не стоит
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.05.17;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.004 c