Перейти к содержанию
Fire Monkey от А до Я

Как убить кнопку кликнув на нее саму


gonzales

Рекомендуемые сообщения

Также изначально удивился данной поднятой темой ("убийство кнопки по клику самой себя"), но подумал, может есть какой случай, что это нужно...

сам НИКОГДА так не делаю! понятно, что это зло! :))

Ссылка на комментарий
14 минут назад, Brovin Yaroslav сказал:

А есть вообще понимание:

У меня - нет.
Емнип, Owner-ом для всех наброшенных на форму компонентов выступает сама форма. Вне зависимости от уровня вложенности визуальных компонентов.
Для невизуальных объектов овнер нужен, если они покладены на форму в дизайн-тайме. Parent-а у невизуального объекта нет, а правило "не ты создал - не тебе удалять" выполняться должно.

Это из того, что на поверхности. А какие реальные причины заставили иметь не только парента, но и овнера, да еще и для дизайн-тайм... Возможно, действительно без них никак.

Давайте только без привлечения ARC "ничего удалять не надо, если и владелец и родитель удалятся, ссылки на объект закончатся и он самоуничтожится".

Ссылка на комментарий
45 минут назад, Brovin Yaroslav сказал:

А есть вообще понимание:

  1. Что такое Овнер для компонентов в делфи?
  2. Какую роль он играет в дизайнере и в рантайме?

Я бы сформулировал вопрос по-другому. Чем отличается Owner и Parent? Для чего нужен тот и другой. Почему это разные объекты? Ярослав, дайте пожалуйста четкое пояснение как разработчик FMX. Я думаю многим здесь это будет интересно.

Ссылка на комментарий

Owner - отвечает за жизненный цикл объекта

Parent - отвечает за расположение в иерархии объектов

отсюда и плясать надо...

Изменено пользователем #WAMACO
Ссылка на комментарий
  • Администраторы
12 минут назад, kami сказал:

У меня - нет.
Емнип, Owner-ом для всех наброшенных на форму компонентов выступает сама форма. Вне зависимости от уровня вложенности визуальных компонентов.
Для невизуальных объектов овнер нужен, если они покладены на форму в дизайн-тайме. Parent-а у невизуального объекта нет, а правило "не ты создал - не тебе удалять" выполняться должно.

Это из того, что на поверхности. А какие реальные причины заставили иметь не только парента, но и овнера, да еще и для дизайн-тайм... Возможно, действительно без них никак.

Давайте только без привлечения ARC "ничего удалять не надо, если и владелец и родитель удалятся, ссылки на объект закончатся и он самоуничтожится".

Ты в принципе все правильно написал. Есть еще сторона дизайнера: где овнер выступает в роли контейнера. Например для дизайнера : форма и фрейм - это контейнеры, которые он обрабатывает + овнер используется дизайнером в том числе для десерилизации.

Это я к тому: что передавать кабы что в виде овнера, а потом удивляться почему это не работает не правильно. Можно было конечно проверку от дурака сделать. Но это накладные расходы, так как нужно пробегаться вверх по родителям, чтобы это проверять. 

Ссылка на комментарий

просто, например, есть кнопка,  Owner будет форма, а Parent  - панель.

если ничего не трогать, то при разрушении формы, разрушится и кнопка, а при разрушении панели, на которой кнопка,

кнопка продолжит жить!

Ссылка на комментарий
54 минуты назад, #WAMACO сказал:

просто, например, есть кнопка,  Owner будет форма, а Parent  - панель.

если ничего не трогать, то при разрушении формы, разрушится и кнопка, а при разрушении панели, на которой кнопка,

кнопка продолжит жить!

но не в FMX !!! в FMX Parent (панель) при своем разрушении разрушит и кнопку. Вот это неправильно.

Ссылка на комментарий
1 час назад, #WAMACO сказал:

Owner - отвечает за жизненный цикл объекта

Parent - отвечает за расположение в иерархии объектов

отсюда и плясать надо...

Owner - отвечает за разрушение "своих" объектов при собственном разрушении.

Parent отвечает за прорисовку "своих" объектов. Какая еще иерархия объектов? визуальная иерархия - да...  было бы неплохо что бы эта иерархия отвечала и за выравнивание объектов - но нет... не знаю когда в delphi будет нормальное выравнивание... может еще лет 20 подождать...

Изменено пользователем slav_z
синт.ошибка
Ссылка на комментарий
2 часа назад, #WAMACO сказал:

Также изначально удивился данной поднятой темой ("убийство кнопки по клику самой себя"), но подумал, может есть какой случай, что это нужно...

сам НИКОГДА так не делаю! понятно, что это зло! :))

в FMX очень удобно делать модальные диалоги поверх всей формы. прозрачный layout сверху (по клику закрывается модальная форма - просто разрушается layout со всем содержимым  - 1 случай) конкретное содержимое кладется на него там, конечно, можно расположить кнопку закрытия диалога и все остальное...  по нажатию на эту кнопку также разрушается layout - 2 случай. кнопка разрушается через разрушение своего Owner-а. Но это тоже самое что и разрушить кнопку по нажатию на саму себя.

Ссылка на комментарий
  • 5 месяцев спустя...

Я, конечно, извиняюсь за то, что поднимаю старую тему, но все жё к какому решению тут пришли? Довольно не хилое обсуждение шло, но при этом кода мало.

По поводу Release в Tokyo он стал deprecated. На данный момент использую такое решение, по смыслу схожее с тем, что было в Release:

TTask.Run(procedure
begin
  Sleep(100);

  TThread.Synchronize(nil, procedure
  begin
    DisposeOf;
  end);
end);

Но может есть вариант получше?

Ссылка на комментарий
6 часов назад, Шамсуддин сказал:

Я, конечно, извиняюсь за то, что поднимаю старую тему, но все жё к какому решению тут пришли? Довольно не хилое обсуждение шло, но при этом кода мало.

По поводу Release в Tokyo он стал deprecated. На данный момент использую такое решение, по смыслу схожее с тем, что было в Release:


TTask.Run(procedure
begin
  Sleep(100);

  TThread.Synchronize(nil, procedure
  begin
    DisposeOf;
  end);
end);

Но может есть вариант получше?

Нееетттт.... только не это! Аааааааа.......!!!!

Ссылка на комментарий

Вот disposeof чот не очень,  и sleep лишний а в целом норм

Вместо самостоятельного убийства я все таки за системный подход.

Сделать так, чтобы сработал механизм arc. Зачистить ссылки на объект

Ссылка на комментарий
1 час назад, krapotkin сказал:

Сделать так, чтобы сработал механизм arc. Зачистить ссылки на объект

Поговаривают, что идёт лютый капец ARC!!!

В новых версиях вроде вырезают каленым железом данный механизм!

Ссылка на комментарий

Если правильно все было сделано, то арк работает ровно так же как и ранее. Создал объект - удали ссылки на него и сделай free. Ровно как и всегда

Ссылка на комментарий
3 часа назад, krapotkin сказал:

Вот disposeof чот не очень,  и sleep лишний а в целом норм

Sleep как подстраховка,  чтобы все "внутренности" обработчика нажатия выполнились. В моём случае, такая задержка не критична и незаметна.

1 час назад, krapotkin сказал:

Создал объект - удали ссылки на него и сделай free. Ровно как и всегда

Я делал так, но если сразу после уничтожение создать в том же контроле объект, то вылетает исключение(было давно, уже не помню какое, что-то типа такой объект уже есть). Поэтому использовал DisposeOf, поскольку он избавляется от объекта сразу.

UPD. Сейчас перепроверил снова с Free, но почему-то исключение перестало вылетать, даже если не удалять на него ссылку, странно... Может это было на андроид.

UPD 2. Во The Free and DisposeOf methods under ARC. Точно, это было на андроид :)

Изменено пользователем Шамсуддин
Ссылка на комментарий

нет никакой подстраховки)). не надо чудесизировать исполнение программы

обработчик работает в главном потоке, и наша задача - дать ему с гарантией завершиться! исключительно для этого мы вызываем Synchronize() из другого потока

программа придет туда не абы когда а только после выполнения всех текущих работ основного потока. То же самое можно достигнуть в windows сделав postMessage()

Ну и создание объекта подчиняется тем же условиям. Если он РЕАЛЬНО не удалился, то самостоятельно убив его через DisposeOf, мы получим с большой вероятностью AV из-за того, что где-то ссылка на него еще есть!

 

Ссылка на комментарий
В 02.07.2019 в 21:20, krapotkin сказал:

нет никакой подстраховки)). не надо чудесизировать исполнение программы

обработчик работает в главном потоке, и наша задача - дать ему с гарантией завершиться! исключительно для этого мы вызываем Synchronize() из другого потока

программа придет туда не абы когда а только после выполнения всех текущих работ основного потока. То же самое можно достигнуть в windows сделав postMessage()

Ну и создание объекта подчиняется тем же условиям. Если он РЕАЛЬНО не удалился, то самостоятельно убив его через DisposeOf, мы получим с большой вероятностью AV из-за того, что где-то ссылка на него еще есть!

 

Перепроверил 3 раза на андроид.

Первый раз без Sleep:

TTask.Run(procedure
begin
  TThread.Synchronize(nil, procedure
  begin
    FBackgroundLayout.Free; //FBackgroundLayout - родительский элемент
  end);
end);

Получил Access violation сразу при нажатии на кнопку.


Второй раз так:

TTask.Run(procedure
begin
  Sleep(100);

  TThread.Synchronize(nil, procedure
  begin
    FBackgroundLayout.Free;
  end);
end);

При первом нажатии исключений нет, но FBackgroundLayout не удаляется(визуально) и соответственно на кнопку можно нажать ещё раз после чего сразу получаем AV, оно и понятно.

 Третий раз, уже основываясь на ваших сообщениях, о том, что нужно везде удалять ссылки, сделал так:

TTask.Run(procedure
begin
  Sleep(100);

  TThread.Synchronize(nil, procedure
  begin
    FBackgroundLayout.Parent.RemoveObject(FBackgroundLayout);
    FBackgroundLayout.Free;
    FBackgroundLayout:= nil;
  end);
end);

И теперь все работает.

 

В моём случае, необходимости удаления подобным образом не было, поскольку ссылки на тот объект я в своём коде не хранил, а потому способ с DisposeOf работал. Но думаю, третий вариант использовать всё же лучше.

 

UPD. Сделал четвертую проверку, перечитав ваше сообщение ещё раз) . Убрал поток:

FBackgroundLayout.Parent.RemoveObject(FBackgroundLayout);
FBackgroundLayout.Free;
FBackgroundLayout:= nil;
//Ну или FreeAndNil(FBackgroundLayout)

И оно заработало! И без каких-либо ошибок.

 

UPD 2. Теперь точно всё) Я вспомнил зачем создавал поток и ставил Sleep. Дело в том, что в Windows приложении, если при нажатии на кнопку удалить его сразу, то не будет сообщения о том, что произошло "MouseUp" кнопки, в связи с чем, рамки приложения (т.е. кнопки сворачивание, закрыть и т.д.) не реагируют на нажатия мыши до того, пока не нажмете на "нажимаемый" элемент в самом приложении. И потому 4 вариант не подходит для Windows приложений.

Изменено пользователем Шамсуддин
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...