【问题标题】:Corona SDK - Cancel timer from within Widget Candy button onPress handlerCorona SDK - 从 Widget Candy 按钮 onPress 处理程序中取消计时器
【发布时间】:2014-03-10 00:58:30
【问题描述】:

我正在尝试取消 Widget Candy 按钮的 onPress 事件处理程序中的计时器。但是,即使我已将 timerId 定义为文件范围内的局部变量,timerId 也始终为零。我是 Lua 开发的新手,所以我假设这个问题与变量范围有关,但我很难找到一种方法来访问计时器变量而不使其成为真正的全局变量(即在没有“local”关键字的情况下声明它)。见下面的代码sn-p。

local countdownTimer = timer.performWithDelay(1000, handleCountdownTimer, countdown);

local answerButton1 = wcandy.NewButton
{
x       = "center",
y       = "55%",
width   = "75%",
name    = "MyButton1",
theme   = "theme_1",
border     = {"normal",6,1, .12,.12,0,.4,  .72,.72,.72,.6},
pressColor = {1,1,1,.25},
caption = "Touch me!",
textAlign   = "center",
fontSize    = "40",
onPress     =   function( EventData )
                    timer.cancel(countdownTimer); -- "countdownTimer" is always nil!!!
                    local button = wcandy.GetHandle("MyButton1");
                    if button:get("caption") == tostring(solution) then
                        questionText:set("caption", "Correct!");
                    else
                        questionText:set("caption", "Wrong!");
                    end
                end
}

【问题讨论】:

  • 我刚想到的一件事:是什么让你说“countdownTimer 总是为零!!!”在取消行,如果是错误消息,您可以打印它,还是在 timer.cancel 之前有打印语句?
  • @Scholli - 我正在使用 Lua Glider IDE,我可以使用调试器检查变量。该变量显示为 nil,并且当我尝试执行它时还报告以下错误:?:0:尝试索引 nil 值消息堆栈回溯:?:在函数 [C]:? ?: 在函数 'cancel' ...nk(builds)\sampleblank(default)\sampleblank\main.lua:40: 在函数 'onPress' ...eblank(default)\sampleblank\scripts\widget_candy.lua:913 : 在函数 <...eblank> 中 ?: 在函数

标签: timer event-handling lua coronasdk


【解决方案1】:

我认为您发布的代码没有任何问题:当 onPress 被调用时,您的 countdownTimer 应该不为零。您不必测试 countdownTimer 是否为零。在创建新按钮之前打印 countdownTimer 以确认它不为零。还可以搜索代码以查找引用该变量的所有位置,并检查是否有任何位置将其设置为 nil。

更新:

您可以尝试的一件事是移动函数并将其设为本地:

local countdownTimer = timer.performWithDelay(1000, handleCountdownTimer, countdown);

local function cancelTimer( EventData )
    timer.cancel(countdownTimer); -- "countdownTimer" is always nil!!!
    local button = wcandy.GetHandle("MyButton1");
    if button:get("caption") == tostring(solution) then
        questionText:set("caption", "Correct!");
    else
        questionText:set("caption", "Wrong!");
    end
end

local answerButton1 = wcandy.NewButton
{
x       = "center",
y       = "55%",
width   = "75%",
name    = "MyButton1",
theme   = "theme_1",
border     = {"normal",6,1, .12,.12,0,.4,  .72,.72,.72,.6},
pressColor = {1,1,1,.25},
caption = "Touch me!",
textAlign   = "center",
fontSize    = "40",
onPress     = cancelTimer
}

更新 2(在@husterk 发现上述内容仍然不起作用之后):

我看不出有什么问题,所以我在我的 corona sim 中对此进行了测试,没有问题,所以问题出在其他地方。这是 main.lua 的完整内容:

local widget = require('widget')

local function handleCountdownTimer(event)
    print('timed out; timer:', event.source)
end

local countdownTimer

local function cancelTimer( event )
    print('cancelling timout, timer:', countdownTimer)
    timer.cancel(countdownTimer) 
end

local answerButton1 = widget.newButton
{
    onPress     = cancelTimer, 
    width = 100,
    height = 100,
    label = 'hello',
    emboss = true
}

countdownTimer = timer.performWithDelay(10000, handleCountdownTimer)
print('timer started:', countdownTimer)

【讨论】:

  • 感谢您的建议,但 onPress 处理程序中的 countdownTimer 绝对为零。但是,如果我在主文件范围内执行相同的 timer.cancel(countdownTimer) 函数,一切正常。似乎事件处理程序在不同的范围内运行(类似于 .NET 中在与 UI 线程不同的线程上运行的事件)。
  • 更新导致同样的问题。我开始怀疑这个问题是否是由 Widget Candy 按钮对象引起的。我也将测试一个标准按钮。如果这能解决问题,我会通知您。
  • 我刚刚测试了从标准按钮事件处理程序中取消计时器,并且发生了同样的问题。我很茫然……
  • 我举了一个有效的例子。您显示的代码没有任何问题,因此问题出在其他地方,您必须在某处将其删除。正如我的回答中所说,搜索所有出现的情况。另请参阅更新。
  • 这很奇怪。因此,如果您在使用 timer.performWithDelay 函数实际设置值之前声明 countdownTimer 局部变量,那么一切正常。但是,如果您在与 timer.performWithDelay 函数相同的行上分配变量,那么它会中断。这有什么原因吗?
【解决方案2】:

尝试像这样取消:

if(countdownTimer~=nil)  -- Check whether timer is triggering or not 
  timer.cancel(countdownTimer)
end

【讨论】:

  • 感谢您的建议,但这无济于事。我需要能够在按下按钮后立即停止计时器。我不能跳过停止计时器,因为我可以看到它仍在运行,即使 countdownTimer 引用在 onPress 事件处理程序中显示为 nil。
  • 试试这个 local tm local number = 0 function fn_counter() number = number + 1 txt_counter.text = number if number >= 10 then timer.cancel(tm) end end tm = timer.performWithDelay( 1000, fn_counter, 0)
猜你喜欢
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多