2016-08-29 5 views
2

次のカウントダウンタイマーコードがあります。大丈夫ですが、停止ボタンを押しても停止しません。このスリーピングプログラムをラケットで止める方法

#lang racket/gui 

(define myframe (new frame% [label "Timer"] [x 500] [y 200])) 
(define tfsecs (new text-field% [parent myframe] [label "Secs:"])) 
(define msgbmi (new message% 
        [parent myframe] [auto-resize #t] [label ""])) 

(define stopflag #f) 
(define (OnButtonPressFn n) 
    (sleep 1) 
    (set! n (sub1 n)) 
    (define m 0) 
    (send msgbmi set-label "") 
    (for((i (in-naturals)) #:break stopflag) 
    (set! m (- n i)) 
    ; (printf "running; i= ~a~n" m) 
    (send msgbmi set-label (number->string m)) 
    (sleep 1))) 

(define startbutton 
    (new button% [parent myframe] [label "Start"] 
     (callback (lambda (b e) 
        (define secs (string->number (send tfsecs get-value))) 
        (when secs (OnButtonPressFn secs)))))) 

(define stopbutton 
    (new button% [parent myframe] [label "Stop"] 
     (callback (lambda (b e) 
        (set! stopflag #t))))) 

(send myframe show #t) 

それは私が0でそれを終了するforループを制限する場合は停止しますが、私はそれが停止ボタンが押されまでに多くの時間が経過する様子を維持したいです。

明らかに、ストップボタンで設定されているストップフラグは、ループ実行中に読み込まれていません。どのようにこれを修正することができますか?ここで停止ボタンを正しく機能させるにはどうすればいいですか?

答えて

1

目的の制御フローに従ってください。

最初に開始ボタンをクリックします。システムによってイベントが生成されます。イベントハンドラ(コールバックが呼び出され)、クリックが処理されます。その後、停止ボタンがクリックされます。システムは新しいイベントを生成し、停止ボタンのイベントハンドラが呼び出されます。

プログラムの問題は、開始ボタンのイベントハンドラが返されないことです。システムは一度に1つのイベントのみを処理するため、イベントハンドラから戻ってこない場合、次のイベントは処理されません。

問題を解決する1つの方法は、実際の作業を行うための新しいスレッドを開始することです:

(define (OnButtonPressFn n) 
    (thread (λ() 
      (sleep 1) 
      (set! n (sub1 n)) 
      (define m 0) 
      (send msgbmi set-label "")    
      (for((i (in-naturals)) #:break stopflag) 
       (set! m (- n i)) 
       ; (printf "running; i= ~a~n" m) 
       (send msgbmi set-label (number->string m)) 
       (sleep 1))))) 

このイベントハンドラは、(イベントループと並行して実行されます)、新しいスレッドを作成し、すぐに戻ります。イベントループは、新しいイベントを処理することができます。その間、新しいスレッドが作業を行います(ここでは番号を印刷しています)。

+0

はい、動作します。ありがとう。私がする必要があった別のものは、停止ボタンによって行われた変更を元に戻すために、startbuttonのコールバックに(set!stopflag #f)を追加することです。 – rnso

関連する問題