wxLua-如何实现取消按钮?

wxLua-如何实现取消按钮?,lua,wxwidgets,coroutine,cancel-button,Lua,Wxwidgets,Coroutine,Cancel Button,我有一个wxLua Gui应用程序,它有一个“运行”按钮。根据选择的选项,运行可能需要很长时间,因此我想实现一个“取消”按钮/功能。但是看起来wxLua中的所有东西都在一个Gui线程上工作,一旦点击Run,按Cancel键什么都不做,运行总是会完成 Cancel基本上将变量设置为true,并且运行的进程定期检查该变量。但是,运行时不会发生取消按钮按下事件 我从来没有使用过合作程序;如果运行进程定期屈服于“取消检查”进程,那么取消事件会发生吗 或者还有其他方法吗?我不使用WXWidgets,但我在

我有一个wxLua Gui应用程序,它有一个“运行”按钮。根据选择的选项,运行可能需要很长时间,因此我想实现一个“取消”按钮/功能。但是看起来wxLua中的所有东西都在一个Gui线程上工作,一旦点击Run,按Cancel键什么都不做,运行总是会完成

Cancel基本上将变量设置为true,并且运行的进程定期检查该变量。但是,运行时不会发生取消按钮按下事件

我从来没有使用过合作程序;如果运行进程定期屈服于“取消检查”进程,那么取消事件会发生吗


或者还有其他方法吗?

我不使用WXWidgets,但我在使用IUP的lua脚本中实现取消按钮的方法是有一个取消标志,该标志在按下按钮时设置,并在运行期间检查进度显示

用法是这样的

ProgressDisplay.Start('This is my progress box',100)
for i=1,100 do
    ProgressDisplay.SetMessage(i.." %")
    fhSleep(50,40)  -- Emulate performing the task 
    ProgressDisplay.Step(1)
    if ProgressDisplay.Cancel() then
        break
    end
end 
ProgressDisplay.Reset()
ProgressDisplay.Close() 
如果要查看ProgressDisplay的定义,请参见:


我不使用WXWidgets,但我在使用IUP的lua脚本中实现取消按钮的方式是有一个取消标志,该标志在按下按钮时设置,并在运行期间检查进度显示

用法是这样的

ProgressDisplay.Start('This is my progress box',100)
for i=1,100 do
    ProgressDisplay.SetMessage(i.." %")
    fhSleep(50,40)  -- Emulate performing the task 
    ProgressDisplay.Step(1)
    if ProgressDisplay.Cancel() then
        break
    end
end 
ProgressDisplay.Reset()
ProgressDisplay.Close() 
如果要查看ProgressDisplay的定义,请参见:

(以下假设“运行”是指同一进程中的长时间运行操作,而不是使用wxecute或wxProcess运行外部进程。)

“取消”事件不会触发,因为通过执行运行逻辑,您没有给UI机会来处理单击事件

为了避免阻塞UI,您需要执行以下操作。单击“运行”按钮时,围绕要运行的函数创建一个共同例程:

coro = coroutine.create(myLongRunningFunction)
此时您的跑步事件已完成。然后,在EVT_IDLE事件中,只要该协同程序尚未完成,您将恢复该协同程序。它看起来像这样:

if coro then -- only if there is a coroutine to work on
  local ok, res = coroutine.resume(coro, additional, parameters)
  -- your function either yielded or returned
  -- you may check ok to see if there was an error
  -- res can tell you how far you are in the process
  -- coro can return multiple values (just give them as parameters to yield)
  if coroutine.status(coro) == 'dead' then -- finished or stopped with error
    coro = nil
    -- do whatever you need to do knowing the process is completed
  end
end
只要进程未完成,您可能需要请求更多空闲事件,因为除非触发了其他事件,否则某些操作系统不会触发空闲事件。假设处理程序具有
event
参数,则可以执行
event:RequestMore(true)
来请求更多空闲事件()

您的长时间运行的进程将需要在适当的时间调用coroutine.yield()(不要太短,因为来回切换会浪费时间,用户不会太长时间注意到UI中的延迟);您可能需要对此进行试验,但基于100毫秒左右的通话间隔的计时器可能会起作用

您可以像现在一样,在空闲事件处理程序或长时间运行的函数中检查Cancel值。我描述的逻辑将使您的应用程序UI有机会按预期处理取消事件。

(以下假设“运行”是指在同一进程中长时间运行的操作,而不是使用wxecute或wxProcess运行外部进程。)

“取消”事件不会触发,因为通过执行运行逻辑,您没有给UI机会来处理单击事件

为了避免阻塞UI,您需要执行以下操作。单击“运行”按钮时,围绕要运行的函数创建一个共同例程:

coro = coroutine.create(myLongRunningFunction)
此时您的跑步事件已完成。然后,在EVT_IDLE事件中,只要该协同程序尚未完成,您将恢复该协同程序。它看起来像这样:

if coro then -- only if there is a coroutine to work on
  local ok, res = coroutine.resume(coro, additional, parameters)
  -- your function either yielded or returned
  -- you may check ok to see if there was an error
  -- res can tell you how far you are in the process
  -- coro can return multiple values (just give them as parameters to yield)
  if coroutine.status(coro) == 'dead' then -- finished or stopped with error
    coro = nil
    -- do whatever you need to do knowing the process is completed
  end
end
只要进程未完成,您可能需要请求更多空闲事件,因为除非触发了其他事件,否则某些操作系统不会触发空闲事件。假设处理程序具有
event
参数,则可以执行
event:RequestMore(true)
来请求更多空闲事件()

您的长时间运行的进程将需要在适当的时间调用coroutine.yield()(不要太短,因为来回切换会浪费时间,用户不会太长时间注意到UI中的延迟);您可能需要对此进行试验,但基于100毫秒左右的通话间隔的计时器可能会起作用

您可以像现在一样,在空闲事件处理程序或长时间运行的函数中检查Cancel值。我描述的逻辑将使您的应用程序UI有机会按预期处理取消事件