2

「実行」ボタンがあるwxLuaGuiアプリがあります。選択したオプションによっては、実行に時間がかかる場合があるため、「キャンセル」ボタン/機能を実装したいと思います。しかし、wxLuaのすべてが1つのGuiスレッドで機能しているように見えます。実行を押すと、[キャンセル]を押しても何も起こらず、実行は常に完了します。

キャンセルは基本的に変数をtrueに設定し、実行中のプロセスはその変数を定期的にチェックします。ただし、実行中にキャンセルボタンを押すイベントは発生しません。

コルーチンを使用したことはありません。実行プロセスが定期的に「チェックのキャンセル」プロセスに移行する場合、キャンセルイベントは発生しますか?

または別の方法はありますか?

4

2 に答える 2

3

(以下では、「実行」とは、同じプロセスで長時間実行され、wxExecuteまたはwxProcessを使用して外部プロセスを実行しないことを意味することを前提としています。)

実行ロジックを実行することにより、UIにクリックイベントを処理する機会が与えられていないため、「キャンセル」イベントはトリガーされません。

UIのブロックを回避するには、次のようなことを行う必要があります。[実行]ボタンをクリックすると、実行する関数の周りにコルーチンが作成されます。

coro = coroutine.create(myLongRunningFunction)

この時点でRunイベントが完了します。次に、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

他のイベントがトリガーされない限り、一部のオペレーティングシステムはIDLEイベントをトリガーしないため、プロセスが終了しない限り、おそらくIDLEイベントをさらに要求する必要があります。ハンドラーにパラメーターがあると仮定すると、さらにIDLEイベントを要求するためにevent実行できます( RequestMore)。event:RequestMore(true)

実行時間の長いプロセスでは、適切なタイミングでcoroutine.yield()を呼び出す必要があります(切り替えに時間を浪費するので短すぎず、ユーザーがUIの遅延に気付くのに長すぎません)。おそらくこれを試す必要がありますが、呼び出しの間に100ミリ秒程度のタイマーベースのものが機能する可能性があります。

現在のように、IDLEイベントハンドラーまたは長時間実行関数のいずれかでキャンセル値を確認できます。私が説明したロジックは、アプリケーションUIにキャンセルイベントを期待どおりに処理する機会を与えます。

于 2012-09-13T18:39:28.013 に答える
1

私は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の定義を確認したい場合は、以下を参照してください。

http://www.fhug.org.uk/wiki/doku.php?id=plugins:code_snippets:progress_bar

于 2012-09-13T18:27:08.133 に答える