Here's a small program that uses canvases and keyboard events. When you press the arrow key, the last one you clicked will appear on the canvas.
#lang racket/gui (define game-canvas% (class canvas% (inherit get-width get-height refresh) ;; direction : one of #f, 'left, 'right, 'up, 'down (define direction #f) (define/override (on-char ke) (case (send ke get-key-code) [(left right up down) (set! direction (send ke get-key-code)) (refresh)] [else (void)])) (define/private (my-paint-callback self dc) (let ([w (get-width)] [h (get-height)]) (when direction (let ([dir-text (format "going ~a" direction)]) (let-values ([(tw th _ta _td) (send dc get-text-extent dir-text)]) (send dc draw-text dir-text (max 0 (/ (- w tw) 2)) (max 0 (/ (- h th) 2)))))))) (super-new (paint-callback (lambda (c dc) (my-paint-callback c dc)))))) (define game-frame (new frame% (label "game") (width 600) (height 400))) (define game-canvas (new game-canvas% (parent game-frame))) (send game-frame show #t)
Each frame has an event space that controls event scheduling. The on-char method is an event handler; it runs in the event handler thread. No more events will be processed until your on-char method completes. Therefore, if you want to do something complicated, you may need to create a separate thread and perform the calculations there. One easy way to do this is to create another event space that does not process events for any frame, but processes the "events" that you send using queue-callback . For example, replace the on-char definition with the following:
(define aux-eventspace (make-eventspace)) (define/override (on-char ke) (parameterize ((current-eventspace aux-eventspace)) (queue-callback (lambda () (case (send ke get-key-code) ((left right up down) (set! direction (send ke get-key-code)) (refresh)) (else (void)))))))
The function specified by queue-callback is run in a separate thread. You can insert some printouts, delays, or something else to convince yourself that the main event space can still handle events, and the other is a callback.
source share