запущен пользовательский скрипт, создающий окно. У окна есть колбек OnClose. Когда пользователь мышкой закрывает окно, нужно завершить работу скрипта. Нет проблем, завершаем.
Когда пользователь закрывает терминал при запущенном скрипте, завершать работу скрипта не нужно, она должна продолжаться автоматом при следующем запуске терминала.
Мне кажется, что такое поведение скрипта не является чем-то необычным и не должно требовать каких то сверхусилий.
Но нихрена! При закрытии терминала первым делом в окно скрипта сразу же приходит колбек OnClose - скрипт его обрабатывает и завершает скрипт. До OnStop дело не доходит даже, этот колбек будет вызван когда то позже.
Получается, что при вызове колбека onclose невозможно понять, что произошло - завершили скрипт или закрыли терминал.
Я чего то не понимаю или ВСЕ НА САМОМ ДЕЛЕ ТАК И ЕСТЬ?
Пользователь
Сообщений: Регистрация: 01.02.2025
06.02.2026 22:59:15
А если я не ошибаюсь, то как мне отличить эти два события? посмотреть состояние главного окна quik? Там будут какие то еще приколы или все стандартно?
OnClose - не колбек окна. Функция SetTableNotificationCallback задает колбек для окна.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 30.01.2015
07.02.2026 08:42:39
Цитата
tohoki написал: Я пробовал искать по форуму, но ничего не нашел
у меня квик 12.8.3.4
запущен пользовательский скрипт, создающий окно. У окна есть колбек OnClose. Когда пользователь мышкой закрывает окно, нужно завершить работу скрипта. Нет проблем, завершаем.
Когда пользователь закрывает терминал при запущенном скрипте, завершать работу скрипта не нужно, она должна продолжаться автоматом при следующем запуске терминала.
Мне кажется, что такое поведение скрипта не является чем-то необычным и не должно требовать каких то сверхусилий.
Но нихрена! При закрытии терминала первым делом в окно скрипта сразу же приходит колбек OnClose - скрипт его обрабатывает и завершает скрипт. До OnStop дело не доходит даже, этот колбек будет вызван когда то позже.
Получается, что при вызове колбека onclose невозможно понять, что произошло - завершили скрипт или закрыли терминал.
Я чего то не понимаю или ВСЕ НА САМОМ ДЕЛЕ ТАК И ЕСТЬ?
Вы ошибаетесь. ---------------------------- Если скрипт создает окно, то у окна есть функция закрытия, но нет кобека закрытия окна. -------------------- OnClose - это колбек закрытие терминала QUIK или выгрузка файла qlua.dll OnStop - это колбек остановки скрипта из диалога управления (т е из окна запуска скрипта) Что не так?
Пользователь
Сообщений: Регистрация: 01.02.2025
07.02.2026 09:15:51
В Спарте дефективных младенцев скидывали со скалы. По крайней мере такова легенда.
но у вас, Николоэз, есть возможность прочитать исходное сообщение несколько раз. Медленно, чтобы попытаться понять его смысл. Попробуйте.
OnClose - не колбек окна. Функция SetTableNotificationCallback задает колбек для окна.
да, верно. Именно об этом я и писал.
если задать при помощи этой функции окну колбек на закрытие, то он вызывается и при закрытии этого окна мышкой и при закрытии терминала. Причем до вызова onstop.
не понимаю, как распознать действия пользователя.
Пользователь
Сообщений: Регистрация: 22.02.2023
07.02.2026 11:09:04
Цитата
tohoki написал: если задать при помощи этой функции окну колбек на закрытие, то он вызывается и при закрытии этого окна мышкой и при закрытии терминала.
Вызывается при закрытии терминала??? У меня так: Колбек окна:
Код
local function event_callback(mw_id, msg, row, col)
if msg == QTABLE_CLOSE then
w_top, w_left, w_bottom, w_right = GetWindowRect(mw_id)
DestroyTable(x2_id)
DestroyTable(mw_id)
OnStop()
end
-- Другие события
end
SetTableNotificationCallback(mw_id, event_callback)
И в OnStop:
Код
function OnStop(c) -- 1-Остановка скрипта, 2-Закрытие QUIK.
if mw_id and c == 1 then
w_top, w_left, w_bottom, w_right = GetWindowRect(mw_id)
DestroyTable(mw_id)
DestroyTable(x2_id)
end
end
написал: если задать при помощи этой функции окну колбек на закрытие, то он вызывается и при закрытии этого окна мышкой и при закрытии терминала.
Вызывается при закрытии терминала??? У меня так: Колбек окна:
Код
local function event_callback (mw_id, msg, row, col)
if msg = = QTABLE_CLOSE then
w_top, w_left, w_bottom, w_right = GetWindowRect (mw_id)
DestroyTable (x2_id)
DestroyTable (mw_id)
OnStop()
end
-- Другие события
end
SetTableNotificationCallback (mw_id, event_callback)
И в OnStop:
Код
function OnStop (c) -- 1-Остановка скрипта, 2-Закрытие QUIK.
if mw_id and c = = 1 then
w_top, w_left, w_bottom, w_right = GetWindowRect (mw_id)
DestroyTable (mw_id)
DestroyTable (x2_id)
end
end
OnClose вообще не используется.
Ok. Будем двигаться медленно и печально.
забудьте про onclose
смотрим на ваш пример
вставьте между строками
if msg = = QTABLE_CLOSE then w_top, w_left, w_bottom, w_right = GetWindowRect (mw_id)
вывод уведомления PrintDbgStr("QTABLE_CLOSE")
а первым оператором функции onstop PrintDbgStr("ONSTOP")
запустите скрипт, debugview и закройте терминал
смотрите в debugview.
там будут строки в таком порядке QTABLE_CLOSE ONSTOP
желающие могут проверить. Я не пробовал и буду рад ошибиться
А теперь сделаем так, чтобы в колбеке QTABLE_CLOSE работа скрипта завершалась. Это нормальное привычное поведение. Закрытие главного окна текстового редактора, майкрософт ворда или самомго терминала квик приводит к прекращению работы программы, а не к продолжению ее работы втихую. Это нормально и привычно везде и всюду, в Windows, Linux и даже, прости господи, macos. Но не в гордости российского программирования от ARQA.
когда мы это сделаем (я не могу предложить код, не знаю как у вас реализован функционал останова скрипта. Но закрытие должно быть немедленным) окажется, что
и при закрытии скрипта и при закрытии терминала мы увидим в debugview только QTABLE_CLOSE и не увидим ONSTOP.
Значит, onstop приходит позже QTABLE_CLOSE. Получается, что действия пользователя неразличимы в момент срабатывания колбека QTABLE_CLOSE, а решения о реакции нужно принимать в нем.
Вот и встаёт вопрос. Как отличить действия пользователя (закрыто окно скрипта или закрыт терминал/завершен сеанс windows) и как по закрытию окна завершить скрипт, а по завершению работы терминала ничего не делать?
я могу, конечно, поставить хук на закрытие окна терминала, но богородицу от этого неудержимо мутит.
Пользователь
Сообщений: Регистрация: 27.01.2017
07.02.2026 12:23:35
DestroyTable нельзя вызывать в колбеке окна - это отражено в документации. Вызывать OnStop руками, тем более в колбеке окна - тоже не надо.
Не ясна суть проблемы. Колбек окна - это транслятор команд в поток main, где все команды и надо обрабатывать. В окне перехватили событие - передали в main, там обработали. Если вызван OnClose, то в нем производите проверки, устанавливаете состояние скрипта (или флаг) в остановлен и поток main уже проверяет это состояние, чтобы не вызывать ничего, т.к. в процессе остановки, а, наоборот, необходимо успеть выполнить процедуры корректного завершения - закрыть окна, закрыть, сохранить открытие файлы. Если в процессе ожидания OnStop не было ошибок выполнения, то скрипт прекрасно запустится вместе с терминалом. А если нет, значит и была ошибка, приведшая к падению main и остановке скрипта до завершения процесса остановки.
Пользователь
Сообщений: Регистрация: 22.02.2023
07.02.2026 12:29:26
Цитата
tohoki написал: как по закрытию окна завершить скрипт, а по завершению работы терминала ничего не делать?
Именно так у меня и происходит. Закрыл окно - скрипт остановился; перезапустил терминал с работающим скриптом - скрипт работает.
написал: как по закрытию окна завершить скрипт, а по завершению работы терминала ничего не делать?
Именно так у меня и происходит. Закрыл окно - скрипт остановился; перезапустил терминал с работающим скриптом - скрипт работает.
благодарю за участие
Пользователь
Сообщений: Регистрация: 01.02.2025
07.02.2026 13:03:25
Цитата
Nikolay написал: DestroyTable нельзя вызывать в колбеке окна - это отражено в документации. Вызывать OnStop руками, тем более в колбеке окна - тоже не надо.
Не ясна суть проблемы. Колбек окна - это транслятор команд в поток main, где все команды и надо обрабатывать. В окне перехватили событие - передали в main, там обработали. Если вызван OnClose, то в нем производите проверки, устанавливаете состояние скрипта (или флаг) в остановлен и поток main уже проверяет это состояние, чтобы не вызывать ничего, т.к. в процессе остановки, а, наоборот, необходимо успеть выполнить процедуры корректного завершения - закрыть окна, закрыть, сохранить открытие файлы. Если в процессе ожидания OnStop не было ошибок выполнения, то скрипт прекрасно запустится вместе с терминалом. А если нет, значит и была ошибка, приведшая к падению main и остановке скрипта до завершения процесса остановки.
это все понятно что и очевидно. Техника разделения по потокам исполнения очевидна и не является вопросом.
Вопрос в надёжном способе интерпретации сигналов о действиях пользователя.
ситуация, когда разные события генерируют одну ту же реакцию (qtable_close) и только потом через неопределенное время приходит уточняющий сигнал (onstop) является скажем так, странной. такая архитектура приводит к тому, .что нормальное человеческое событийное программирование придется разбавлять невнятным винегретом из каких то переменных и непонятных таймаутов с потолка.
спасибо всем за участие. Подожду ответ от разработчиков, если им будет что сказать видимо, придется на лету добавить в терминал ещё один метод ))))
Пользователь
Сообщений: Регистрация: 22.02.2023
07.02.2026 13:17:14
Цитата
tohoki написал: при закрытии скрипта и при закрытии терминала мы увидим в debugview только QTABLE_CLOSE и не увидим ONSTOP.
Автору надо, чтобы скрипт останавливался при закрытии таблицы.
Пользователь
Сообщений: Регистрация: 02.01.2026
07.02.2026 14:49:27
Цитата
tohoki написал: и при закрытии скрипта и при закрытии терминала мы увидим в debugview только QTABLE_CLOSE и не увидим ONSTOP
Значит main завершился раньше. Надо ставить таймаут в конце main с ожиданием сигнала из OnClose / OnStop. Если по завершении этого времени сигнал не получен, считать, что таблица закрыта пользователем.
Цитата
tohoki написал: такая архитектура приводит к тому, .что нормальное человеческое событийное программирование придется разбавлять невнятным винегретом из каких то переменных и непонятных таймаутов с потолка.
Да.
Пользователь
Сообщений: Регистрация: 22.02.2023
07.02.2026 15:14:55
Цитата
Йцукен написал: Автору надо, чтобы скрипт останавливался при закрытии таблицы
Цитата
Ziveleos написал: Именно так у меня и происходит.Закрыл окно - скрипт остановился; перезапустил терминал с работающим скриптом - скрипт работает.
Под окном здесь подразумевается таблица, не окно терминала.
Закрытие главного окна текстового редактора, майкрософт ворда или самомго терминала квик приводит к прекращению работы программы, а не к продолжению ее работы втихую. Это нормально и привычно везде и всюду, в Windows, Linux и даже, прости господи, macos. Но не в гордости российского программирования от ARQA.
Вы путаете кислое с зеленым. --------------------------- Окно в редакторе текста - это область работы самого приложения. аналогично приложениям windows или Linux. -------------------- Но в самом приложении пользователь может и делает кучу окон которые открывает и закрывает по надобности. ----------------------- Таблица В скрипте - это не главное окно скрипта. ------------------------- Терминал QUIK который Вы осваиваете с трудом. ----------------- Когда закроете окно с графиков то терминал закроется? ---------------------- Для программирования надо не только читать школьные учебники по истории, но и учебники программирования.
Пользователь
Сообщений: Регистрация: 01.02.2025
07.02.2026 16:34:36
Всем спасибо я подожду, возможно техподдержка этого терминала сможет мне ответить
специально для Nikolz: Не нужно ничего больше писать. Большое тебе спасибо.
Пользователь
Сообщений: Регистрация: 12.05.2020
07.02.2026 19:36:11
Цитата
tohoki написал: Когда пользователь закрывает терминал при запущенном скрипте, завершать работу скрипта не нужно, она должна продолжаться автоматом при следующем запуске терминала.
Код
while _RUN_ do
---Тело основного цикла скрипта --
end
if TBL_QUIK then -- Если используются таблицы QUIK
-- #### Задержка sleep нужна чтобы установился признак запуска скрипта при перезапуске QUIK.
-- Иначе при перезапуске QUIK не будет перезапущен скрипт.--
-- При нормальном завершении QUIK, если есть таблицы QUIK, они удаляются (и вызываются коллбеки QTABLE_CLOSE)
-- Если при этом нет задержки, то скрипт завершается и не выставляется признак необходимости его перезапуска
-- при запуске QUIK. Признак TBL_QUIK устанавливается в основной пользовательской таблице QUIK.
-- Длительность задержки выбрана экспериментально.
sleep(1000)
end
написал: Когда пользователь закрывает терминал при запущенном скрипте, завершать работу скрипта не нужно, она должна продолжаться автоматом при следующем запуске терминала.
Код
while _RUN_ do
---Тело основного цикла скрипта --
end
if TBL_QUIK then -- Если используются таблицы QUIK
-- #### Задержка sleep нужна чтобы установился признак запуска скрипта при перезапуске QUIK.
-- Иначе при перезапуске QUIK не будет перезапущен скрипт.--
-- При нормальном завершении QUIK, если есть таблицы QUIK, они удаляются (и вызываются коллбеки QTABLE_CLOSE)
-- Если при этом нет задержки, то скрипт завершается и не выставляется признак необходимости его перезапуска
-- при запуске QUIK. Признак TBL_QUIK устанавливается в основной пользовательской таблице QUIK.
-- Длительность задержки выбрана экспериментально.
sleep ( 1000 )
end
Идея понятна.
поменять местами во времени реакцию на колбеки qtable_close и onstop, чтобы они обрабатывались в нормальном порядке. Именно в том, как они реально возникли. Ну как должно быть у нормальных людей.
Хорошая мысль и при этом простая.
Пользователь
Сообщений: Регистрация: 02.01.2026
08.02.2026 08:52:00
Цитата
tohoki написал: поменять местами во времени реакцию на колбеки qtable_close и onstop, чтобы они обрабатывались в нормальном порядке. Именно в том, как они реально возникли.
Первым должен быть OnClose, а после - QTABLE_CLOSE.