1

Тема: Визуальный интерфейс VCLua в QUIK

Для создания интерфейса с пользователем в программах на Lua среди других разработана библиотека VCLua.

С точки зрения внутреннего устройства определенная "изюминка" ее состоит в том, что написана она на языке Pacscal, в то время как подавляющее большинство других библиотек написаны на C/C++. Само по себе это довольно здорово, т.к. для компиляции ее можно использовать Delphi или Lazarus, для которых них создано  просто огромное количество визуальных компонент, реализующих различные элементы экранного интерфейса, что при определенном навыке позволяет легко расширять эту библиотеку, добавляя в нее новые необходимые элементы. Впрочем, при использовании этой библиотеки из Lua уже и так доступно весьма большое количество элементов визуального интерфейса (полный перечень их можно найти в файле controls.txt в дистрибутиве).

Домашняя страничка проекта [url]http://vclua.99k.org/[/url]
Последняя выложенная версия значится VCLua v0.3.5.

Стоит отметить довольно бедную справку по данной библиотеке и крайне малое количество примеров.

Установка

Вариант 1. Официальная сборка:
Для установки идем вот по этой ссылке [url]http://files.luaforge.net/releases/vclua/vclua/VCLua-0.3.5[/url] и скачиваем файл со скомпилированной (готовой к использованию) библиотекой и, желательно, файл с документацией (уж какая есть):

  • vclua-0.3.5-win32.zip

  • vclua-0.3.3-doc.zip

Вариант 2. Исправленная сборка с этого сайта:
Я буду постепенно исправлять и немного дополнять эту библиотеку.
Ссылка для скачивания и история изменений есть в [url=https://quik2dde.ru/viewtopic.php?pid=59#p59]следующем сообщении этой темы[/url]; в виде одного [url=https://quik2dde.ru/static-img/26/vcl.zip]архива vcl.zip[/url].

Далее все общее для любого варианта.

Из папки, куда распаковался архив vclua-0.3.5-win32.zip или vcl.zip, копируем в каталог с терминалом QUIK единственный файл:

  • vcl.dll (из папки bin для варианта 1)

Если вы до этого не ставили никакие другие дополнительные Lua-библиотеки, то вам еще необходимо скопировать файл lua5.1.dll из дистрибутива Lua с сайта lua.org, копируем тоже в каталог с QUIK. Подробнее где что брать см. отдельную тему рядом на этом форуме.
В варианте 2 файл lua5.1.dll добавлен в скачиваемый архив.

Вот и все. На этом установка закончена, можно использовать VCLua.

Использование

Создадим файл vcl-test-01.lua в текстовом редакторе и скопируем в него такой текст:

-- НЕ ИСПОЛЬЗУЙТЕ КОД ЭТОГО ПРИМЕРА В QUIK! Он приведен лишь как пример этапов изучения VCLua!
-- Читайте сообщение дальше, дальше есть правильный код
require "vcl"

mainForm = VCL.Form("mainForm")

mainForm.Caption = "My first VCLua application"
mainForm._= { position="podesktopcenter", height=400, width=600 }

mainForm.onclosequery = "onCloseQueryEventHandler" 

function onCloseQueryEventHandler(Sender)
    return true -- the form can be closed
end

mainMenu = VCL.MainMenu(mainForm,"mainMenu")
mainMenu:LoadFromTable({
    {name="mmfile", caption="&File", 
        submenu={
            {caption="Exit", onclick="onMenuExitClick", shortcut="Ctrl+F4"}, 
        }
    }
})

function onMenuExitClick()
    mainForm:Close()
end

mainForm:ShowModal()

function main()
    message("main started", 1)
end

Скрипт этот сделан на основе самого простого примера из поставки VCLua и даже еще несколько упрощен. Добавим файл vcl-test-01.lua в QUIK (Таблицы -> Lua  -> Доступные скрипты) и запустим на выполнение. Появляется простейшее окно в меню, при этом как и с другими фреймворками визуализации для Lua в QUIK видим типичные проблемы: форма конечно создана и присутствует на экране, но скрипт отображается в состоянии "не запущен", да и сообщение "main started" не отображается, что означает, что поток с main() не запущен, т.е. скрипт еще даже не прошел инициализацию. Никакие обработчики событий тоже не работают.

Оно и понятно, ведь мы, как обычно, стоим в строке модального отображения главной формы:

 mainForm:ShowModal() 

И только когда мы форму закрываем - появляется сообщение "main started"!

Как делать правильно

Самой приятной особенностью библиотеки VCLua оказалось то, что она абсолютно отлично поддерживает немодальное отображение форм, в том числе и главной формы! Собственно в этом смысле понятие "главной формы" сразу исчезает, т.к. любые формы (т.е. окна интерфейса) можно отображать в любое время, VCLua от наличия или отсутствия форм работать не перестает! Давайте немного изменим предыдущий пример; основное, что будет изменено – будет вызываться метод Show вместо метода ShowModal. Это позволит нам не останавливаться на инициализации скрипта, а выполнять обычную нормальную работу QLua дальше. Сохраним текст в файле vcl-test-02.lua ([url=https://quik2dde.ru/static-img/26/vcl-test-02.lua]скачать[/url]).

 require "vcl"

mainForm = VCL.Form("mainForm")

mainForm.Caption = "VCLua in QUIK"
mainForm._= { position="podesktopcenter", height=150, width=300}

mainMenu = VCL.MainMenu(mainForm,"mainMenu")
mainMenu:LoadFromTable({
    {name="mmfile", caption="&File", 
        submenu={
            {caption="Exit", onclick="onMenuExitClick", shortcut="Ctrl+F4"}, 
        }
    }
})

label = VCL.Label(mainForm,"Label")
label.Top = 30
label.Left = 50
label.Caption = "VCLua in QUIK"
label.Font.Size = 20

function onMenuExitClick()
    OnStop()
end

mainForm:Show()

is_run = true    

function main()
    while is_run do
        sleep(50)
    end
end

function OnStop()
    is_run = false
    mainForm:Free()
end

Запустив скрипт, увидим такую картинку:

https://quik2dde.ru/static-img/26/vcl-test-02.png
Обратите внимание:

  • скрипт корректно находится в состоянии "запущен"

  • при нажатии на "Остановить" скрипт завершается и окно закрывается

  • при выборе из меню на окне пункта File -> Exit окно закрывается и скрипт переходит в состояние "остановлен"

Остановка скрипта "по требованию" осуществляется здесь:

function OnStop()
    is_run = false
    mainForm:Free()
end

Т.е. в обработчике OnStop завершается цикл в main, для чего присваивается false переменной is_run, и уничтожается форма путем вызова метода Free().

Чтобы закрыть форму через ее меню - просто вызываем OnStop из обработчика пункта меню:

function onMenuExitClick()
    OnStop()
end

Это же то, что и хотелось! Скрипт вполне корректно уживается внутри QUIK, реагируя на события, завершаясь по требованию и т.д.

Чуть сложнее пример

Попробуем добавить обработчик события и отображение информации из этого обработчика.
Например, в событии OnAllTrade будем суммировать объем всех сделок по двум инструментам: LKOH и SBER. Файл будет называться vcl-test-03.lua ([url=https://quik2dde.ru/static-img/26/vcl-test-03.lua]скачать[/url]).

require "vcl"

mainForm = VCL.Form("mainForm")

mainForm.Caption = "VCLua in QUIK"
mainForm._= { position="podesktopcenter", height=150, width=300}

mainMenu = VCL.MainMenu(mainForm,"mainMenu")
mainMenu:LoadFromTable({
    {name="mmfile", caption="&File", 
        submenu={
            {caption="Exit", onclick="onMenuExitClick", shortcut="Ctrl+F4"}, 
        }
    }
})

label = {}
label["SBER"] = VCL.Label(mainForm,"Label1")
label["LKOH"] = VCL.Label(mainForm,"Label2")

label["SBER"].Top = 10
label["SBER"].Left = 10
label["LKOH"].Top = 30
label["LKOH"].Left = 10

cnt = {}
cnt["LKOH"] = 0
cnt["SBER"] = 0

qty = {}
qty["LKOH"] = 0
qty["SBER"] = 0

val = {}
val["LKOH"] = 0
val["SBER"] = 0

function onMenuExitClick()
    OnStop()
end

mainForm:Show()

is_run = true    

function main()
    while is_run do
        sleep(50)
    end
end

function OnStop()
    is_run = false
    mainForm:Free()
end

function OnAllTrade(trade)
    if is_run == false then
        return
    end

    if (trade.seccode == "LKOH") or (trade.seccode == "SBER") then
        cnt[trade.seccode] = cnt[trade.seccode] + 1
        qty[trade.seccode] = qty[trade.seccode] + trade.qty
        val[trade.seccode] = val[trade.seccode] + trade.value
        label[trade.seccode].Caption = trade.seccode .. " (" .. cnt[trade.seccode] .. ") " .. qty[trade.seccode] .. " = " .. val[trade.seccode]
    end
end

https://quik2dde.ru/static-img/26/vcl-test-03.gif

Да оно отлично работает! В нашем окне выводится количество сделок (в скобках), суммарное количество лотов в сделках и суммарный объем сделок. Разумеется, все это подсчитывается только с начала работы скрипта.

Небольшие пояснения по коду. Первые три строчки в OnAllTrade нужны для того, чтобы предотвратить падения терминала после остановки скрипта (как известно, в версии 6.4 есть ошибка: обработчики вызываются и после завершения скрипта, приводя к падению терминала)

function OnAllTrade(trade)
    if is_run == false then
        return
    end

2

Re: Визуальный интерфейс VCLua в QUIK

Известные проблемы

Все это хорошо, но есть и проблемы, конечно. Некоторые в самой библиотеке, некоторые привнесены используемым подходом.

  • [s]Если добавить обработчик события интерфейса VCLua (например, для пункта меню или ToolBar'а - то при задействовании этого обработчика (например, клике по кнопке ToolBar'а, терминал QUIK падает[/s] - это не так, обработчики работают корректно, позже добавлю пример

  • При нажатии на "крестик" закрываня окна - окно не закрывается. Если при этом по стандартным правилам прописать обработчик OnClose для формы - при нажатии крестика терминал падает

  • [s]Вместо русских букв отображаются "вопросики"[/s] (победил, с.м. следующий пост)

  • Если при активной форме,  созданной из VCLua, нажать Ctrl-F4, то закроется последнее активное окошко внутри QUIK'а(!)

  • Если внутри VCLua происходит исключение - QUIK зависает намертво. Причем словить исключение очень легко: достаточно ошибиться в наименовании свойства какого-либо компонента.

Но библиотека мне очень понравилась, так что постараюсь разобраться с причиной указанных проблем и поподробнее ее поизучать в следующих сериях.

3

Re: Визуальный интерфейс VCLua в QUIK

Про русские буквы: оказывается хитрый Lazarus (версии FreePascal) по-особенному "поддерживает" UniCode: все строковые значения (тип String) в нем трактуются как заданные в кодировке UTF8, при этом в Windows API вызываются функции в суффиксом W, предварительно конвертируя значения строк в UNICODE.

Самый простой выход - задавать константы в кодировке UTF8, если это возможно.

Результаты

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

[url=https://quik2dde.ru/static-img/26/vcl.zip]Скачать поправленный файл vcl.dll[/url]
(Исходники выложу, но позже. Кому очень нужно и сейчас - пишите письма.)

История изменений:

Версия от 08.03.2013
- добавлен метод SetCellColor(Col,Row,Color) в StringGrid
- добавлен метод Release() для формы, его можно безопасно вызывать из обработчиков событий формы для ее закрытия

Версия от 18.01.2013
- исправлен вывод русских букв для StringGrid

Версия от 14.01.2013
- исправлен вывод русских букв для published-свойств компонент

4

Re: Визуальный интерфейс VCLua в QUIK

< reserved >

5

Re: Визуальный интерфейс VCLua в QUIK

< reserved >

6

Re: Визуальный интерфейс VCLua в QUIK

< reserved >

7 (2013-01-31 22:48:18 отредактировано sam)

Re: Визуальный интерфейс VCLua в QUIK

вопрос: как получить выбранный элемент комбобокса?

listbox["secs"]:GetText()[1]

так выбирается первый из списка элементов, а для текущего выбранного не нашел свойства.
сам разобрался, просто .Text

второй вопрос в силе, комбобокс не хочется использовать как костыль

2 вопрос: какой в vclua аналог текстбокса?

8

Re: Визуальный интерфейс VCLua в QUIK

sam,

если я правильно понял контекст, то в вашем случае видимо будет вот так:

listbox["secs"]:GetText()[listbox["secs"]:Index()+1]

Вообще странно, конечно, что для listbox в VCLua реализован только метод GetText(), который возвращает все элементы в виде таблицы. Надо будет добавить метод, возвращающий текст конктерного элемента по индексу.

Я, правда, не совсем понял: вы про комбобокс говорите или листбокс? тексте у вас комбобокс, а в коде - listbox...

Чтобы докопаться до этого - накидал такой вот примерчик. При нажатии на кнопку под ListBox'ом в Label выводится текст из активного элемента. Наверное есть смысл добавить проверку на значение, возвращаемое listbox:Index() - если равно -1, то ничего не выбрано.

-- vcl-test-04.lua
-- List-box sample --

require "vcl"

mainForm = VCL.Form("mainForm")

mainForm.Caption = "ListBox in VCLua"
mainForm._= { position="podesktopcenter", height=190, width=300}

mainMenu = VCL.MainMenu(mainForm,"mainMenu")
mainMenu:LoadFromTable({
    {name="mmfile", caption="&File", 
        submenu={
            {caption="Exit", onclick="onMenuExitClick", shortcut="Ctrl+F4"}, 
        }
    }
})

listbox = VCL.ListBox(mainForm,"List1")
listbox._ = { Top=5, Left=5, Width=120, Height=125 }
listbox:Add("Text 1")
listbox:Add("Text 2")
listbox:Add("Text 3")

button = VCL.Button(mainForm,"Button1")
button._ = { Top=10, Left=140, width=145, Caption="Show Selected Text", onclick = "onButton1Click" }

label =  VCL.Label(mainForm,"Label1")
label._ = { Top=135, Left=10 }

function onButton1Click(sender)
  label.Caption = listbox:GetText()[listbox:Index() + 1]
end

function onMenuExitClick()
    OnStop()
end

mainForm:Show()

is_run = true    

function main()
    while is_run do
        sleep(50)
    end
end

function OnStop()
    is_run = false
    mainForm:Free()
end

По поводу текстбокса - видмо речь про Edit? т.е. нужен элменет, куда можно ввести текст я правильно понял?

9

Re: Визуальный интерфейс VCLua в QUIK

да я обозвал просто таблицу элементов листбокс,  чтобы получить выбранный элемент(текст) в комбобоксе, достаточно посмотреть listbox["secs"].Text

да, Edit оказалось то что нужно(кто ж названия такие дает элементам)

10

Re: Визуальный интерфейс VCLua в QUIK

Когда скачиваете VClua, то там в комплекте идет документация. Кроме всего прочего архив содержит очень полезный файл  - vcldoc.lua
Попробуйте его запустить, там информация по всем компонентам, их свойствам и методам. Ну и заглянуть в его содержимое тоже интересно.

11

Re: Визуальный интерфейс VCLua в QUIK

Только честно: вы пытались по этой справке что-то сделать?
Она, конечно, как-бы есть, но толку с нее не особо много )

12

Re: Визуальный интерфейс VCLua в QUIK

Не только пытался но и делал.
Дело, конечно, хозяйское, но мне он показался очень полезным и познавательным. Особенно на фоне практически полного отсутствия другой документации.

13

Re: Визуальный интерфейс VCLua в QUIK

Подскажите, я что-то не нашел, можно ли в StringGrid раскрасить отдельную ячейку ?

14

Re: Визуальный интерфейс VCLua в QUIK

В стандартной поставке библиотеки VCLua возможна раскраска разными цветами только целиком столбцов.

https://quik2dde.ru/static-img/26/vclua-color-grid-cell.png

require "vcl"

mainForm = VCL.Form("mainForm")
mainForm._= { position="podesktopcenter", height=300, width=400, Color="clRed" }

grid = VCL.StringGrid(mainForm,"grid")
grid._ = { align = "alClient", RowCount = 3, AutoEdit = False, FixedCols = 1, FixedRows = 1, Flat = True }

grid:SetColParams({
  {Width=100, Alignment="taRightJustify", Color=16711680, Title={Caption="Col1", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Color=65280,    Title={Caption="Col2", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Color=255,      Title={Caption="Col3", Alignment="taCenter"}},
})

is_run = true

mainForm:Show()

function main()
  while is_run do
    sleep(50)
  end
end

function OnStop()
  is_run = false
  mainForm:Free()
end

Обратите внимание на вызов grid:SetColParams(). Здесь в свойстве Color задается цвет ячеек столбца. Речь идет и "нефиксированных" ячейках (которые обычно белого цвета).

Значение Color вычисляется по формуле:

      Color = (R * 256 + G) * 256 + B
            где: R, G, B - интенсивность компоненты цвета красной, зеленой и синей


Записал себе добавить в будущих версиях метод что-то вроде SetCellColor() для грида. Актуально?

15 (2013-02-06 21:52:21 отредактировано Rilin)

Re: Визуальный интерфейс VCLua в QUIK

admin пишет:

В стандартной поставке библиотеки VCLua возможна раскраска разными цветами только целиком столбцов.


      Color = (R * 256 + G) * 256 + B
            где: R, G, B - интенсивность компоненты цвета красной, зеленой и синей


Записал себе добавить в будущих версиях метод что-то вроде SetCellColor() для грида. Актуально?

Соответственно, и цвет шрифта я пока нашел, как поменять только у всего грида.
Конечно актуально, даже стакан нормально не нарисовать.

По цвету я уже разобрался. Хотя в исходниках есть константы цветов clBlue и т.д., но при подстановке не работает. Я ставил hex-значения, 0xFF00, 0x00FF - соответственно зеленый и красный.

PS Хотя в одном из скриншотов есть закраска одной ячейки, правда только фиксированной.
[url]http://vclua.99k.org/images/vclua_controls_shot.JPG[/url]

16

Re: Визуальный интерфейс VCLua в QUIK

Rilin пишет:

По цвету я уже разобрался. Хотя в исходниках есть константы цветов clBlue и т.д., но при подстановке не работает. Я ставил hex-значения, 0xFF00, 0x00FF - соответственно зеленый и красный.

Конечно проще в HEX-задавать, я просто не посмотрел как задавать HEX-константы в Lua. Спасиб за подсказку!

Rilin пишет:

PS Хотя в одном из скриншотов есть закраска одной ячейки, правда только фиксированной.

Для фиксированных ячеек цвет действительно можно отдельно свой устанавливать в свойстве Color для Title:

https://quik2dde.ru/static-img/26/vclua-color-grid-cell-2.png

require "vcl"

mainForm = VCL.Form("mainForm")
mainForm._= { position="podesktopcenter", height=300, width=400, Color="clRed" }

grid = VCL.StringGrid(mainForm,"grid")
grid._ = { align = "alClient", RowCount = 5, AutoEdit = False, FixedCols = 0, FixedRows = 2, Flat = True }

grid:SetColParams({
  {Width=100, Alignment="taRightJustify", Color=0xFF0000, Title={Color=0x998800, Caption="Col1", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Color=0x00FF00, Title={Color=0x009988, Caption="Col2", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Color=0x0000FF, Title={Color=0x990088, Caption="Col3", Alignment="taCenter"}},
})

is_run = true

mainForm:Show()

function main()
  while is_run do
    sleep(50)
  end
end

function OnStop()
  is_run = false
  mainForm:Free()
end

17

Re: Визуальный интерфейс VCLua в QUIK

а когда у Вас будет время дописать метод SetCellColor()  ?

18 (2013-02-12 20:32:45 отредактировано admin)

Re: Визуальный интерфейс VCLua в QUIK

Добавил для StringGrid функцию SetCellColor. Еще добавил метод Release для формы, теперь можно ее закрывать "крестиком" (с обязательной остановкой скрипта!).

Ссылка для скачивания приведена в 3-м посте этой темы.

Для примера сделал стакан с подсветкой в зависимости от объема. Сразу отмечу, что в приведенном скрипте не все полностью доделано (в частности не обыгран момент, когда котировок станет меньше, чем выводилось в прошлый раз, надо чистить). Но будем считать что это просо модельный пример. Форму можно закрывать "крестиком".

https://quik2dde.ru/static-img/26/vclua-grid-cell-color.gif

require "vcl"

CLASS = "QJSIM"
SEC   = "SBER"

mainForm = VCL.Form("mainForm")
mainForm._= { position="podesktopcenter", height=240, width=320,
              OnClose = "OnFormClose" }

grid = VCL.StringGrid(mainForm,"grid")
grid._ = { align = "alClient", RowCount = 11, AutoEdit = False, FixedCols = 0, FixedRows = 1, Flat = True }

grid:SetColParams({
  {Width=100, Alignment="taRightJustify", Title={Caption="Продажа", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Title={Caption="Цена", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Title={Caption="Покупка", Alignment="taCenter"}},
})

is_run = true

mainForm:Show()

function main()
  while is_run do
    sleep(50)
  end
end

function OnStop()
  is_run = false
  mainForm:Release()
end

function OnFormClose(Sender, CloseAction)
  is_run = false
  mainForm:Release()
end


function RGB2Color(r, g, b)
  return ((r*256)+g)*256+b
end

function OnQuote(class_code, sec_code)

  -- отслеживаем котировки только по указанному инструменту
  if (class_code ~= CLASS) or (sec_code ~= SEC) then
    return
  end

  local qt = getQuoteLevel2(class_code, sec_code)
  local i
  local max_q = 0

  -- перенесем и покрасим bid

  for i = 0, qt.bid_count+0 do
    grid:SetCell(1, 5-i, qt.bid[qt.bid_count-i].price)
    grid:SetCell(2, 5-i, qt.bid[qt.bid_count-i].quantity)
    local qty = qt.bid[qt.bid_count-i].quantity+0
    if qty > max_q then
      max_q = qty
    end
    if i >= 4 then  -- переносим не более 5 котировок
      break
    end
  end

  for i = 0, qt.bid_count+0 do
    local c = 220 - math.ceil((220-30) / max_q * qt.bid[qt.bid_count-i].quantity)
    grid:SetCellColor(1, 5-i, RGB2Color(c, 255, c))
    grid:SetCellColor(2, 5-i, RGB2Color(c, 255, c))
    if i >= 4 then  -- переносим не более 5 котировок
      break
    end
  end

  -- перенесем и покрасим offer

  max_q = 0

  for i = 0, qt.offer_count+0 do
    grid:SetCell(1, 6+i, qt.offer[i+1].price)
    grid:SetCell(0, 6+i, qt.offer[i+1].quantity)
    local qty = qt.offer[i+1].quantity+0
    if qty > max_q then
      max_q = qty
    end
    if i >= 4 then  -- переносим не более 5 котировок
      break
    end
  end


  for i = 0, qt.bid_count+0 do
    local c = 220 - math.ceil((220-30) / max_q * qt.offer[i+1].quantity)
    grid:SetCellColor(1, 6+i, RGB2Color(c, c, 255))
    grid:SetCellColor(0, 6+i, RGB2Color(c, c, 255))
    if i >= 4 then  -- переносим не более 5 котировок
      break
    end
  end

end

19 (2013-02-12 11:21:08 отредактировано Rilin)

Re: Визуальный интерфейс VCLua в QUIK

Спасибо за проделанную работу!


Только у меня Ваш скрипт ругался на nil переменные
attempt to perform arithmetic on global 'xxxxxx' (a nil value)


, пришлось их объявить в начале скрипта
cur_color=0;
max_color=0;
col_num=0;
row_num=0;

20

Re: Визуальный интерфейс VCLua в QUIK

Rilin,

Да, есть беда. Я просто забыл убрать из текста обработчик OnAllTrade(), оставшийся от каких-то экспериментов. Скрипт в предыдущем посте поправил. Спасибо!

21

Re: Визуальный интерфейс VCLua в QUIK

admin пишет:
  for i = 0, qt.bid_count+0 do
....
    i = i + 1
    if i > 4 then  -- переносим не более 5 котировок
      break
    end
  end

а i +1 здесь не лишнее ?

admin пишет:
  -- перенесем и покрасим offer

  max_q = 0
  for i = 0, qt.bid_count+0 do
....

здесь наверное qt.offer_count, хотя не принципиально.

22

Re: Визуальный интерфейс VCLua в QUIK

admin пишет:
  for i = 0, qt.bid_count+0 do
....
    i = i + 1
    if i > 4 then  -- переносим не более 5 котировок
      break
    end
  end

а i +1 здесь не лишнее ?

Вы правы, конечно лишнее!! как-то много я наошибался.
Вот только странная закадка: котировки из стакана при этом переносились правильно, без пропусков. Как так?? какой-то есть, похоже, неведовый мне нюанс в Lua.
(Наверное, счетчик цикла внутри цикла изменять бесполезно, он изменяется, конечно (это явно видно по тому, что еще и условие с i>4 на i>=4 пришлось поправить), но для каждой итерации цикла похоже берется всегда следующиее значение какое положено, вне зависимости от того, как счетчик был изменен внутри тела цикла; занятно, но это только догадка)


admin пишет:
  -- перенесем и покрасим offer

  max_q = 0
  for i = 0, qt.bid_count+0 do
....

здесь наверное qt.offer_count, хотя не принципиально.

Наверное, в данном месте действительно произойдет корректное преобразование типа в числовое значение (в отличии от доступа по индексу к таблице котировок), но я в этом месте сделал прибавлением нуля "явное преобразование типа" в число. Для верности. (Ведь qt.offer_count имеет тип "строка", такую вот странность подарили нам разработчики)

23

Re: Визуальный интерфейс VCLua в QUIK

admin пишет:
  -- перенесем и покрасим offer

  max_q = 0
  for i = 0, qt.bid_count+0 do
....

здесь наверное qt.offer_count, хотя не принципиально.

Наверное, в данном месте действительно произойдет корректное преобразование типа в числовое значение (в отличии от доступа по индексу к таблице котировок), но я в этом месте сделал прибавлением нуля "явное преобразование типа" в число. Для верности. (Ведь qt.offer_count имеет тип "строка", такую вот странность подарили нам разработчики)


не, +0 это правильно, иначе не выходит, берется строка "20.0000000" (для forts)

скопировано с bid-a, нужно поменять на offer

24

Re: Визуальный интерфейс VCLua в QUIK

Подправил под себя Ваш скрипт. Спасибо за идеи.

max_q  общий для bid & offer  - лучше видно маркетмейкера
сохранил полный стакан (20 котировок для фортса)
Сортировку поставил привычней для себя.

require "vcl"

CLASS = "SPBFUT"
SEC   = "SiH3"

mainForm = VCL.Form("mainForm")
mainForm._= { height=620, width=190,
              OnClose = "OnFormClose" }

grid = VCL.StringGrid(mainForm,"grid")
--grid.DefaultRowHeight=15
grid._ = { align = "alClient", RowCount = 41, AutoEdit = False, FixedCols = 0, FixedRows = 1, Flat = True, DefaultRowHeight=15 }

grid:SetColParams({
  {Width=60, Alignment="taRightJustify", Title={Caption="Продажа", Alignment="taCenter"}},
  {Width=60, Alignment="taRightJustify", Title={Caption="Цена", Alignment="taCenter"}},
  {Width=60, Alignment="taRightJustify", Title={Caption="Покупка", Alignment="taCenter"}},
})

is_run = true

mainForm:Show()

function main()
  while is_run do
    sleep(50)
  end
end

function OnStop()
  is_run = false
  mainForm:Release()
end

function OnFormClose(Sender, CloseAction)
  is_run = false
  mainForm:Release()
end

function RGB2Color(r, g, b)
  return ((r*256)+g)*256+b
end

function OnQuote(class_code, sec_code)

  -- отслеживаем котировки только по указанному инструменту
  if (class_code ~= CLASS) or (sec_code ~= SEC) then
    return
  end

  local qt = getQuoteLevel2(class_code, sec_code)
  local i
  local max_q = 0

  -- перенесем и покрасим bid

  for i = 1, qt.bid_count+0 do
    grid:SetCell(1, 20+i, math.ceil(qt.bid[qt.bid_count-i+1].price))
    grid:SetCell(2, 20+i, math.ceil(qt.bid[qt.bid_count-i+1].quantity))
    local qty = qt.bid[qt.bid_count-i+1].quantity+0
    if qty > max_q then
      max_q = qty
    end
  end

  
  -- перенесем и покрасим offer

  --max_q = 0

  for i = 1, qt.offer_count+0 do
    grid:SetCell(1, 21-i, math.ceil(qt.offer[i].price))
    grid:SetCell(0, 21-i, math.ceil(qt.offer[i].quantity))
    local qty = qt.offer[i].quantity+0
    if qty > max_q then
      max_q = qty
    end
  end


  for i = 1, qt.offer_count+0 do
    local c = 220 - math.ceil((220-30) / max_q * qt.offer[i].quantity)
    grid:SetCellColor(1, 21-i, RGB2Color(c, c, 255))
    grid:SetCellColor(0, 21-i, RGB2Color(c, c, 255))
  end

  for i = 1, qt.bid_count+0 do
    local c = 220 - math.ceil((220-30) / max_q * qt.bid[qt.bid_count-i+1].quantity)
    grid:SetCellColor(1, 20+i, RGB2Color(c, 255, c))
    grid:SetCellColor(2, 20+i, RGB2Color(c, 255, c))
  end

  
end

25

Re: Визуальный интерфейс VCLua в QUIK

Привет !
Использовал вариант RIlin в чистом виде окно с таблицей создается но пустая ... попробовал sec = "SiH3" заменить на sec = "RIH3" получаю "Disk Full" ...
попробовал такую комбинацию ...
require "vcl"

mainForm = VCL.Form("mainForm")
mainForm._= { position="podesktopcenter", height=300, width=400, Color="clRed" }

grid = VCL.StringGrid(mainForm,"grid")
grid._ = { align = "alClient", RowCount = 5, AutoEdit = False, FixedCols = 0, FixedRows = 2, Flat = True }

grid:SetColParams({
  {Width=100, Alignment="taRightJustify", Color=0xFF0000, Title={Color=0x998800, Caption="Col1", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Color=0x00FF00, Title={Color=0x009988, Caption="Col2", Alignment="taCenter"}},
  {Width=100, Alignment="taRightJustify", Color=0x0000FF, Title={Color=0x990088, Caption="Col3", Alignment="taCenter"}},
})

is_run = true

mainForm:Show()

function main()
  while is_run do
--grid:SetCell(1, 5, 66)
--grid:SetCell(2, 5, 777)
c = 100
grid:SetCellColor(1, 5, RGB2Color(c, 255, c))
grid:SetCellColor(2, 5, RGB2Color(c, 255, c))

    sleep(50)
  end
end

function OnFormClose(Sender, CloseAction)
  is_run = false
  mainForm:Release()
end

function OnStop()
  is_run = false
  mainForm:Free()
end

function RGB2Color(r, g, b)
  return ((r*256)+g)*256+b
end

таблицу раскрашенную показывает и закрывает квик и луа-окно .... что интересно если с = 100 закоментить то окно-луа создается с раскрашенной таблицей но пишет мол в функции RGB2Color не определена 'r'
Версия квика 6.5.2.11 ставил vclua как у Вас тут рекомендованно