[Решено]Как выполнить что-либо в модальном окне?

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

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

[Решено]Как выполнить что-либо в модальном окне?

Сообщение SilverShadow » 12.12.2015 13:29:04

И не изобрёл ли я велосипед?

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

Если показывать форму через .Show, то всё нормально. Импорт идёт, данные обновляются. Но окно немодальное со всеми вытекающими.

В случае .ShowModal - всё виснет после отрисовки формы и дальше процесс не идёт. Я понимаю - код основной формы прерывается, а вот вызываемую-то за что?

После долгих мыканий решил проблему так: по созданию формы присваиваю переменной FirstRun значение True, а в событии onActivate - если FirstRun, то FirstRun := False и затем DoSomething (собственно процедура импорта).
Видел в сетях вариант с таймером, но это то же, что делаю я, только в профиль и сложнее.

Нет ли более простого/правильного способа сделать искомое? Ещё раз подчеркну - на вызываемой форме нет элементов управления. Форма создаётся динамически перед вызовом, по завершению операции - уничтожается.
Последний раз редактировалось SilverShadow 12.12.2015 18:30:35, всего редактировалось 1 раз.
SilverShadow
новенький
 
Сообщения: 22
Зарегистрирован: 10.03.2010 17:48:59

Re: Как выполнить что-либо в модальном окне?

Сообщение daesher » 12.12.2015 14:01:17

Насколько я понимаю, всю логику в случае показа модального диалогового окна надо делать в нём - событие OnShow - это то, что должно быть перед её отображением, а дальше да, лучше всего получить управление либо по таймеру или по нажатию чего-то на модальной форме.
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: Как выполнить что-либо в модальном окне?

Сообщение SilverShadow » 12.12.2015 14:08:54

Оно даже не диалоговое, скорее - информационное. И прерывать его я не даю, ибо нефиг.
По нажатию(клавиши или мышки) - не вариант, а вдруг не нажмут? Ну и таймер - излишен, зачем огород городить? Моё решение с on_activate изящнее выходит.
SilverShadow
новенький
 
Сообщения: 22
Зарегистрирован: 10.03.2010 17:48:59

Re: Как выполнить что-либо в модальном окне?

Сообщение resident » 12.12.2015 14:48:03

SilverShadow писал(а):Нет ли более простого/правильного способа сделать искомое?

Пару строк - завести счетчик и через каждую, к примеру, сотню считанных строк вызывать отклик
Код: Выделить всё
if (Count div 1000) = 0 then Application.ProcessMessages;

з.ы. К счетчику и прогрессбар можно прикрутить, если есть возможность оценить общее количество.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как выполнить что-либо в модальном окне?

Сообщение SilverShadow » 12.12.2015 14:57:12

А где этот счётчик прописать? Как он управление получит?
P.S. Наверное, всё-таки (iCycle mod 100) = 0 ?
SilverShadow
новенький
 
Сообщения: 22
Зарегистрирован: 10.03.2010 17:48:59

Re: Как выполнить что-либо в модальном окне?

Сообщение daesher » 12.12.2015 15:48:23

SilverShadow писал(а):Оно даже не диалоговое, скорее - информационное. И прерывать его я не даю, ибо нефиг.

Может быть, для таких целей больше подойдёт что-то вроде ToolWindow? Тогда как главную форму можно на время расчётов сделать нерабочей (Disable).
Вопрос про Application.ProcessMessages тоже важен, но он касается не столько ShowModal, сколько логики расчётов.
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: Как выполнить что-либо в модальном окне?

Сообщение resident » 12.12.2015 17:33:13

SilverShadow писал(а):А где этот счётчик прописать?

где
SilverShadow писал(а):данные обновляются


********
SilverShadow писал(а):P.S. Наверное, всё-таки (iCycle mod 100) = 0 ?

да :)
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как выполнить что-либо в модальном окне?

Сообщение SilverShadow » 12.12.2015 18:13:06

resident писал(а):где
SilverShadow писал(а):данные обновляются


daesher писал(а):ToolWindow? Тогда как главную форму можно на время расчётов сделать нерабочей


Проблема в том, что после .ShowModal ни счётчик прописать, ни сделать главную форму нерабочей(я это и безо всяких инструментов могу) не-по-лу-чит-ся!
А Application.ProcessMessages я и так каждый цикл считывания строки делаю, так что избыточно эту процедуру вызывать нет никакой необходимости.
SilverShadow
новенький
 
Сообщения: 22
Зарегистрирован: 10.03.2010 17:48:59

Re: Как выполнить что-либо в модальном окне?

Сообщение Лекс Айрин » 12.12.2015 18:19:47

SilverShadow, а кто мешает это сделать перед показом формы?

И да, кстати, модальное окно оно и должно блокировать вызывающую форму. Так что, если хотите работать в окне ее вызывающем, то выберете другой метод показа формы. А что блокируется модальная форма... видимо, придется переделать ее обработчик.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как выполнить что-либо в модальном окне?

Сообщение SilverShadow » 12.12.2015 18:30:07

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

Всем спасибо большое за ответы!
SilverShadow
новенький
 
Сообщения: 22
Зарегистрирован: 10.03.2010 17:48:59

Re: [Решено]Как выполнить что-либо в модальном окне?

Сообщение resident » 12.12.2015 19:15:18

SilverShadow писал(а):Я добился того, что мне требовалось получить от модального окна.

Как?
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: [Решено]Как выполнить что-либо в модальном окне?

Сообщение daesher » 13.12.2015 09:24:03

SilverShadow писал(а):Проблема в том, что после .ShowModal ни счётчик прописать, ни сделать главную форму нерабочей(я это и безо всяких инструментов могу) не-по-лу-чит-ся!

В случае с ToolWindow ShowModal не нужно. Оно будет всегда висеть поверх вызывающей формы.
С другой стороны, зачем Вам модальность? Её главная задача - получить ModalResult от окна после нажатия соответствующей кнопки, отображая модальное окно всегда поверх (правда, бывают казусы, если модальное окно свернуть). Второстепенная задача - заблокировать вызывающее окно, пока открыто модальное. В вашем случае ModalResult не нужен, остаётся блокировка вызывающего окна, которую можно сделать и так. Или я что-то упустил?
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: [Решено]Как выполнить что-либо в модальном окне?

Сообщение olegy » 13.12.2015 22:49:02

SilverShadow писал(а):Нет ли более простого/правильного способа сделать искомое?

Изучи TThread, станет намного легче и удобнее. Через PostMessage посылай переменные(или сигналы состояния) на форму. Так работают все серьезные визуальные компоненты.

SilverShadow писал(а):В случае .ShowModal - всё виснет после отрисовки формы и дальше процесс не идёт. Я понимаю - код основной формы прерывается, а вот вызываемую-то за что?

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

SilverShadow писал(а):Видел в сетях вариант с таймером, но это то же, что делаю я, только в профиль и сложнее.
TTimer прямой потомок от TThread.
olegy
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.12.2015 18:35:07

Re: [Решено]Как выполнить что-либо в модальном окне?

Сообщение Лекс Айрин » 19.12.2015 12:56:40

Имитация модального поведения диалога

при вызове формы form1.Enable:=false;
в обработчике события onClose form1.Enable:=True;

формы показывать как обычно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: [Решено]Как выполнить что-либо в модальном окне?

Сообщение SilverShadow » 21.12.2015 18:12:19

resident писал(а):
SilverShadow писал(а):Я добился того, что мне требовалось получить от модального окна.

Как?

по созданию формы присваиваю переменной FirstRun значение True, а в событии созданной формы onActivate - если FirstRun, то FirstRun := False и затем DoSomething (собственно процедура импорта).

Добавлено спустя 14 минут 50 секунд:
daesher писал(а):В вашем случае ModalResult не нужен, остаётся блокировка вызывающего окна, которую можно сделать и так. Или я что-то упустил?

Нет, всё именно так. Но имитация модального окна через Form.Enabled := False работает не совсем так, как истинно модальное окно, даже с установленным свойством Form.FormStyle fsStayOnTop

Добавлено спустя 10 минут 18 секунд:
olegy писал(а):Изучи TThread, станет намного легче и удобнее.

Ну, собственно, по этому пути и придётся идти. Просто из-за одной формы огород городить не хотелось.
SilverShadow
новенький
 
Сообщения: 22
Зарегистрирован: 10.03.2010 17:48:59

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 243

Рейтинг@Mail.ru