function OnStop (signal)
StopFlag = true
return 1000 -- Тайм-аут 1 сек вместо стандартных 5
end
function Create (caption, rowNum, cols)
local t_id = AllocTable()
for i = 1, #cols do -- name * type width
assert (1==AddColumn (t_id,i,cols[i][1],true,cols[i][2],cols[i][3])
,string.format ("%2d %s %s %s", i, tostring(cols[i][1])
,tostring (cols[i][2]), tostring (cols[i][3])))
end -- * false - all cells invisible
assert (1 == CreateWindow (t_id))
assert (SetWindowCaption (t_id, caption))
local top, left, bottom, right = GetWindowRect (t_id)
local totalWidth = right - left + 10 -- Эмпирика |
local frameHeight = 60 --"- |
local rowHeight = 20 --"- |
for i = 1, rowNum do
local row = InsertRow (t_id, -1)
assert (row == i)
assert (SetCell (t_id, row, 1, "row".. i))
for j = 2, #cols do
local val = i * 10 + j
assert (SetCell (t_id, row, j, tostring(val), val))
end
end
assert (SetWindowPos (t_id, left, top
,totalWidth, frameHeight + rowHeight * rowNum))
return t_id
end -- Cre ate ()
function main()
local rowNum = 2
local cols = {
{"Column1", QTABLE_STRING_TYPE, 10,}
,{"Column2", QTABLE_INT_TYPE, 10,}
,{"Column3", QTABLE_DOUBLE_TYPE, 10,}
}
local t_id = Create ("Caption", rowNum, cols)
while not IsWindowClosed (t_id) do
if StopFlag then
message ("Destroying ".. t_id)
if DestroyTable (t_id) then -- Завершение!
message ("Destroying success ".. t_id)
else
message ("Destroying failed ".. t_id)
end
break
end
sleep (10)
end -- while
end -- main()
В моём скрипте закодировано его закрытие не сразу после закрытия таблицы DestroyTable, а после вывода сообщения о закрытии таблицы. Так что неправда ваша, что закрытие реализовано в моём скрипте. Это закрытие реально - в операторе DestroyTable> который должен возвоащать логическое значение, но вопреки документации - не возвращает ничего. Вчитайтесь пожалуйста в код цикла while not IsWindowClosed (t_id) do...
В каком потоке управления выполняется вызов функции DestroyTable() в цикле while not IsWindowClosed (t_id) do... ? Если в том же, что и заголовок цикла, то проверка IsWindowClosed() никак не может сработать раньше возврата значения из DestroyTable() и обработки этого значения в операторе if DestroyTable(t_id) then... Обработка логического значения из DestroyTable() завершается выводом message и оператором break, что исключает срабатывание IsWindowClosed (t_id) в заголовке цикла while. Но печатается только перед функцией DestroyTable(), а сразу после неё - скрипт уже завершён.
Ростислав Дм. Кудряшов написал: В каком потоке управления выполняется вызов функции DestroyTable()
Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ). OnStop в любом случае завершает скрипт, поэтому DestroyTable не выполнена и созданная в скрипте таблица существует после завершения скрипта. Если что то надо делать с таблицами по кнопке завершить, то это надо делать в функции OnStop.
Ростислав Дм. Кудряшов написал: В каком потоке управления выполняется вызов функции DestroyTable()
Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ). OnStop в любом случае завершает скрипт, поэтому DestroyTable не выполнена и созданная в скрипте таблица существует после завершения скрипта. Если что то надо делать с таблицами по кнопке завершить, то это надо делать в функции OnStop.
Полагаю, что не так. -------------------- Поток, если не создается специально для функции, определяется местом вызова. ---------------------- Все колбеки ( в том числе ОnStop ) вызываются в основном потоке VMLua (т е в потоке терминала). --------------------------- Функция DestroyTable в данном примере вызывается в потоке Main.
Зачем полагать, когда можно проверить. Переставьте DestroyTable в OnStop.
2.
Цитата
nikolz написал: Функция DestroyTable в данном примере вызывается в потоке Main.
Вы точно знаете как устроена DestroyTable? Не точно, но скорее всего, это реализовано следующим образом. При том, что DestroyTable вызывается в main, она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается в потоке терминала, но он занят более интересным делом : остановкой скрипта (удаляет поток main и перестает обрабатывать коллбеки, созданные в нем, так как исчезнет контекст их выполнения).
Зачем полагать, когда можно проверить. Переставьте DestroyTable в OnStop.
2.
Цитата
nikolz написал: Функция DestroyTable в данном примере вызывается в потоке Main.
Вы точно знаете как устроена DestroyTable? Не точно, но скорее всего, это реализовано следующим образом. При том, что DestroyTable вызывается в main, она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается в потоке терминала, но он занят более интересным делом :: : остановкой скрипта (удаляет поток main и перестает обрабатывать коллбеки, созданные в нем, так как исчезнет контекст их выполнения).
Что-то у Вас не то. Колбек не создается в процессе исполнения. Колбек - это код функции , он создан при загрузке программы. Если он вызывается в main то вызов это и есть исполнение.
Скорее не коллбек, а какой-то семафор, нужный для операций с окнами, заблокирован от момента нажатия на кнопку "Остановить" до завершения. Не только DestroyTable(), любые операции с таблицей не выполняются. Если к примеру вызвать SetWindowCaption(), возврата из нее не будет, но после таймаута остановки заголовок окна таки изменится.
paluke написал: Не только DestroyTable(), любые операции с таблицей не выполняются.
Цитата
TGB написал: Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ).
Оказывается, после захода управления в OnStop для кода main() функция DestroyTable() не может выполняться штатным образом. Если нужно отреагировать на OnStop, надо туда же поместить и вызовы DestroyTable(). После захода в OnStop() функция main() может делать ещё кое-что, но хотелось бы знать полный список ограничений на этот случай. То ли я плохо прочитал документацию по Quik Lua, то ли документация не полная.