Iup Lua 回调——我做错了什么?

Iup Lua callback -- what am I doing wrong?

我正在使用 Lua 5.1 和 IUP 3.5,并尝试使用列表回调来根据所选地点填充地址列表。 (该列表是一个编辑框,所以我需要在适当的时候处理它,但让我们先处理基础知识)。我显然对如何执行此操作存在根本性的误解。

代码:

function MakeAnIupBox
    --make some more elements here
    listPlace = iup.list{}
    listPlace.sort = "YES"
    listPlace.dropdown = "YES" 
    --populate the list here
    --now handle callbacks
    listPlace.action = function(self) PlaceAction(text, item,  state) end
end

function PlaceAction(text, item, state)
    listAddress.REMOVEITEM = "ALL"
    if state == 1 then -- a place has been selected
    --code here to populate the Addresses list
    end
end

iup documentation 将列表的操作回调描述为

ih:action(text: string, item, state: number) -> (ret: number) [in Lua]

但是,当我 运行 这段代码时,我得到:

我也试过将回调编码为

function MakeAnIupBox
    --make some more elements here
    listPlace = iup.list{}
    listPlace.sort = "YES"
    listPlace.dropdown = "YES" 
    --populate the list here
end
function listPlace:action (text, item, state)
    listAddress.REMOVEITEM = "ALL"
    if state == 1 then -- a place has been selected
        --code here to populate the Addresses list
    end
end 

但是 运行 失败:错误是 attempt to index global 'listPlace' (a nil value)

我不想在 "MakeAnIupBox" 中嵌入回调,因为我希望它(以及其他关联的回调)成为多个 Lua 程序的可重用组件,这些程序都处理类似数据集,但来自不同的用户界面。

问题出在 Lua 用法上。

在第一种情况下,请记住:

function ih:action(text, item, state)

翻译成这样:

function action(ih, text, item, state)

所以它缺少 ih 参数。

第二种情况,listCase只有在调用MakeAnIupBox后才存在。您可以通过在 MakeAnIupBox 范围内声明函数来解决这个问题。

如果你不想在你的函数中嵌入回调函数,你可以先定义它,然后再将它分配给你指定的目的地。

function Callback(self, a, b)
   -- do your work ...
end

function CallbackUser1()
    targetTable = { }
    targetTable.entry = Callback
end

function CallbackUser2()
    otherTargetTable = { }
    otherTargetTable.entry = Callback
end

此解决方案需要参数始终相同。

注:以下所有定义相同

function Table:func(a, b) ... end
function Table.func(self, a, b) ... end
Table.func = function(self, a, b) ... end

根据 Antonio Scuri 的建议,该建议并不完全明确,我已经确定代码需要阅读:

function MakeAnIupBox
    --make some more elements here
    listPlace = iup.list{}
    listPlace.sort = "YES"
    listPlace.dropdown = "YES" 
    --populate the list here
    --now handle callbacks
    listPlace.action = function(self, text, item, state) PlaceAction(listPlace, text, item,  state) end
end

function PlaceAction(ih, text, item, state)
    listAddress.REMOVEITEM = "ALL"
    if state == 1 then -- a place has been selected
    --code here to populate the Addresses list
    end
end