2017-02-25 174 views
0

我想使用以下代碼在畫布上顯示圖像列表。但是,會出現一個空框架,直到整個'for'循環運行,纔會顯示圖像,然後在框架中顯示最終效果。動畫畫布上的圖像列表

#lang racket/gui 
(require 2htdp/image) 

(define frame (new frame% 
        [label "Example"] 
        [width 500] 
        [height 500])) 

(send frame show #t) 
; (sleep 1) ; tried this to allow time for frame to show properly; does not help; 

(new canvas% [parent frame] 
    [paint-callback 
     (lambda (canvas dc) 
     (for ((i imglist))  ; imglist is a list of images to be displayed @ 1/second. 
      (send dc clear) 
      (send dc draw-bitmap 
        (image->bitmap i) 
        20 20) 
      ; (send dc flush)  ; this statement also does not help; 
      (sleep 1)    ; to show animation effect from list of images; 
     ))]) 

的圖像 - >位功能是:;來源:https://lists.racket-lang.org/users/archive/2014-December/065110.html

(define (image->bitmap image) 
    (let* ([width (image-width image)] 
     [height (image-height image)] 
     [bm (make-bitmap width height)] 
     [dc (send bm make-dc)]) 
    (send dc clear) 
    (send image draw dc 0 0 0 0 width height 0 0 #f) 
    bm)) 

在哪裏的問題,怎麼能解決呢?

回答

1

paint-callback是爲了快速更新畫布,然後返回。 當它返回時,系統知道畫布已更新。

一種方法來做你想做的:1)引入一個參數來保存當前顯示的圖像。 2)使paint-callback繪製當前圖像。 3)製作一個單獨的線程,每秒更改當前圖像。

注意:下面我在image->bitmap的寬度和高度上加了+1。圓的邊緣被切斷。

#lang racket/gui 
(require 2htdp/image) 

(define images (list (circle 30 "outline" "red") 
        (circle 20 "outline" "red") 
        (circle 10 "outline" "red") 
        (circle 5 "outline" "red"))) 

(define current-image (make-parameter (first images))) 

(define (image->bitmap image) 
    (let* ([width (+ (image-width image) 1)] 
     [height (+ (image-height image) 1)] 
     [bm  (make-bitmap width height)] 
     [dc  (send bm make-dc)]) 
    (send dc clear) 
    (send image draw dc 0 0 0 0 width height 0 0 #f) 
    bm)) 

(define frame (new frame% 
        [label "Example"] 
        [width 500] 
        [height 500])) 

(define canvas (new canvas% [parent frame] 
        [paint-callback 
        (lambda (canvas dc) 
         (send dc clear) 
         (send dc draw-bitmap (image->bitmap (current-image)) 20 20))])) 

(send frame show #t) 

(thread (λ() 
      (let loop ([is images]) 
      (cond 
       [(null? is) (loop images)] 
       [else  (current-image (first is)) 
          (send canvas on-paint) 
          (sleep 1) 
          (loop (rest is))])))) 
+0

是的,它工作得很好。我發現我也可以用「(發送canvas get-dc)」來獲取dc對象,然後在無限循環中對其進行繪製位圖,但是框架關閉按鈕不起作用,並且該過程必須從DrRacket IDE。使用線程的解決方案沒有這樣的問題。 – rnso

+0

我已經添加了這個作爲回答,以清楚地顯示它。 – rnso

0

以下工作:

(define images (list (circle 30 "outline" "red") 
        (circle 20 "outline" "red") 
        (circle 10 "outline" "red") 
        (circle 5 "outline" "red"))) 

(define (image->bitmap image) 
    (let* ([width (image-width image)] 
     [height (image-height image)] 
     [bm (make-bitmap width height)] 
     [dc (send bm make-dc)]) 
    (send dc clear) 
    (send image draw dc 0 0 0 0 width height 0 0 #f) 
    bm)) 

(define frame (new frame% [label "Frame"] [width 300] [height 300])) 
(define canvas (new canvas% [parent frame])) 
(define dc (send canvas get-dc)) 

(send frame show #t) 
(sleep/yield 1) 

(let loop() 
    (for ((i images)) 
    (send dc clear) 
    (send dc draw-bitmap 
      (image->bitmap i) 
      20 20) 
    (sleep 0.5)) 
    (loop)) 

然而,幀顯示的動畫並不接近,但必須從IDE停止。