Уничтожаю Button, обнуляется DrawGrid

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

arra
новенький
Сообщения: 27
Зарегистрирован: 30.03.2013 22:58:27

Уничтожаю Button, обнуляется DrawGrid

Сообщение arra »

Доброго дня.
Понадобилось мне сделать некую стартовую кнопку, которая делала бы начальные настройки и самоубивалась. Повесил динамическое создание на OnCreate формы:

Код: Выделить всё

procedure TMainForm.FormCreate(Sender: TObject);
var
  Baton:Tbutton;
begin
  Baton:=Tbutton.Create(MainForm);
  Baton.Name:='StartButton';
  Baton.Caption:='Старт!';
  baton.Left:=215;
  Baton.Top:=300;
  baton.Width:=315;
  baton.Height:=115;
  Baton.Parent:=MainForm;
  baton.OnClick:=@StartIgry;
end;


В процедуре StartIgry идёт отрисовка ячеек DrawGrid, потом

Код: Выделить всё

Tbutton(Sender).Destroy;


Так вот, после нажатия на кнопку в DrawGrid на мгновение мелькают данные и вжик - снова девственно чистый компонент. Если закомментировать

Код: Выделить всё

Tbutton(Sender).Destroy;


то DrawGrid остаётся заполненным. Но мне-то надо убить кнопку! И как вообще может быть связано её уничтожение и отрисовка Drawgrid?

Убунту 12.04, Lazarus 1.0.8
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

[b]arra[/b, ]уничтожай кнопку в процедуре обработки самой кнопки.
arra
новенький
Сообщения: 27
Зарегистрирован: 30.03.2013 22:58:27

Сообщение arra »

Что значит " в процедуре обработки самой кнопки". Я её уничтожаю в процедуре, которая повешена на OnClick кнопки. Какая ещё может быть процедура обработки?
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

Компонент не может быть уничтожен во время выполнения его метода. Лично у меня Ваш код вызывает ошибку, что совершенно верно. Объект должен быть уничтожен из вне после отработки его метода. На старом Lazarus я как-то (не помню уже) обходил эту ситуацию.
Сделайте уничтожение кнопки в событии другого компонента... А до возникновения события другого компонента просто спрячьте кнопку.

Код: Выделить всё

TButton(Sender).Hide;
Последний раз редактировалось VirtUX 19.07.2013 19:52:46, всего редактировалось 1 раз.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

arra, я уже попросил удалить то сообщение...
ибо понял, что ошибся.
Кстати, а что мешает ее просто скрыть?
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

И еще (просто из любопытства)... Зачем Вы создаете кнопку в конструкторе формы? Почему бы не сделать ее в дизайнере?..
arra
новенький
Сообщения: 27
Зарегистрирован: 30.03.2013 22:58:27

Сообщение arra »

Наверно, я просто скрытие и сделаю.
virtUX, просто на месте этой кнопки будут другие элементы. Если всё создавать в дизайнере, перегружена будет форма, неудобно проектировать.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

arra, можно, кстати, попытаться передернуть фрейм.
Alex2013
долгожитель
Сообщения: 3237
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Да просто Tbutton(Sender).Visible :=false; зачем обязательно дистроить ?
или Tbutton(Sender).Destroy;замени на Tbutton(Sender).Free;
(Может по Destroy не освобождается из списка контролов в mainForm ? )
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

Это очень старый баг (особенность?) LCL. Нельзя удалить компонент внутри его обработчика, последствия будут ужасны, вплоть до свертывания пространственно-временного континуума :-)

В Delphi - это спокойно можно делать, если что.

Обычно я это решал через скрытие, но когда действительно требовалось удаление кнопки по щелчку - приходилось извращаться с временным таймером.
Alex2013
долгожитель
Сообщения: 3237
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Гм... А может все проще ?

Button1.Enabled:=false;
Button1.Visible:= false;
Button1.Free;
Только что сработало без видимых последствий
Ubuntu 11.04 ..
Lazarus 0.9.28.2-12 r22277 FPC 2.4.0 i386-linux-gtk 2 (beta) :wink:
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

Значит, пофиксили. А может, это только для Windows, там же разные обработки событий, в принципе.
VirusFree
новенький
Сообщения: 11
Зарегистрирован: 22.07.2011 03:11:56

Сообщение VirusFree »

Сдаётся мне что автор неосвоил, что рисовать на канве компонентов нужно в соответствующих обработчиках событий, а не где попало.
Вызывать Destroy экземпляров класса TButton в их обработчиках OnClick можно, а вы тут балаган развели.
Не позорте форум тупыми ответами, а то новички заходят и думают что Pascal и Lazarus - го*но :lol:
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

VirusFree

Вызывать Destroy экземпляров класса TButton в их обработчиках OnClick можно, а вы тут балаган развели.


Windows XP/2008, fpc 2.4.2, Lazarus 0.9.30

Простейшее приложение с

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Free ;
end; 



приводит к Access Violation, и это еще хорошо - раньше бывало и SIGSEGV вываливал, а то и вообще рушило сеанс Проводника.

"Поздравляю вас, гражданин, соврамши!"

Lazarus, конечно, не го..но, но и не для слабаков. Он - инструмент для опытных разработчиков. А это не одно и тоже.
VirusFree
новенький
Сообщения: 11
Зарегистрирован: 22.07.2011 03:11:56

Сообщение VirusFree »

Хм, и правда в Windows крэшится, извиняюсь. Что помешало разработчикам безопасно обработать сообщение незнаю.
В Linux не крешится. Но остальное остается в силе.
Ответить