在Racket的同一窗口中逐帧显示图像

时间:2014-07-08 10:39:40

标签: functional-programming racket

我有三张相同尺寸的小图片。我想一个接一个地展示它们。

(define new1-bitmap 
(make-bitmap 
 (send bird-bitmap get-width) 
 (send bird-bitmap get-height)))

 (define dc-crop 
  (new bitmap-dc% [bitmap new1-bitmap]))

 (define f-crop 
  (new frame% [label "Random"]))
 (send f-crop show #t)

 (send dc-crop draw-bitmap-section 
    bird-bitmap 
            0 
            0 
            0 
            (round(* (/ (send bird-bitmap get-height) 3) 2)) 
            (send bird-bitmap get-width)
            (round(/ (send bird-bitmap get-height) 3)))
 (void 
  (new message% [parent f-crop] [label new1-bitmap]))
 (sleep 3)
 (send dc-crop draw-bitmap-section 
    new1-bitmap 
            0 
            0 
            0 
            (round(/ (send bird-bitmap get-height) 3)) 
            (send bird-bitmap get-width)
            (round(/ (send bird-bitmap get-height) 3)))
  (void 
  (new message% [parent f-crop] [label new1-bitmap]))
  (sleep 3)
  (send dc-crop draw-bitmap-section 
    new1-bitmap 
            0 
            0 
            0 
            0
            (send bird-bitmap get-width)
            (round(/ (send bird-bitmap get-height) 3)))
(void 
 (new message% [parent f-crop] [label new1-bitmap]))

以上是我认为可行的代码。它只拍摄三张图像并试图以3秒的间隔一个接一个地显示它们。此外,最终的GUI比其他GUI长三倍。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

可以使用2htdp库创建一个带动画的简单窗口。 2htdp/universe是一个方便的地方,可以开始对主要产生副作用的简单应用进行原型设计。

示例代码使用Racket附带的一些图标以方​​便使用。

#lang racket

(require 2htdp/image
         2htdp/universe)

(define image1 (bitmap icons/stop-16x16.png))
(define image2 (bitmap icons/bug09.png))
(define image3 (bitmap icons/break.png))

(define image-list (list image1 image2 image3))

(run-movie 3 image-list)

使用racket/gui的更复杂的示例需要实现timer%而不是使用sleep因为sleep acts on the thread level。看来,当直接从源代码运行时,Racket希望将两个写入队列排队到画布然后进入休眠状态,然后清空队列并连续进行两次写入。

第二个棘手的问题是嵌套发送来访问画布的绘图上下文。

以下代码示例源自this thread on the Racket email list。它显示我当前的一只狗的图像,等待一秒,然后显示我以前的一只狗的图像。

#lang racket/gui
(require 2htdp/image)
(provide (all-defined-out))


(define image1 (make-object bitmap% "scarlett.jpg"))
(define image2 (make-object bitmap% "witty2.jpg"))
(define my-frame (instantiate frame%("my frame")))

(define mcan%
  (class canvas%
    (override  on-paint)
    (define on-paint
      (lambda()(send (send this get-dc)
                     draw-bitmap image1 0 0)))        
    (super-instantiate())))

(define mcan (new mcan% (parent my-frame)
                  (min-width (image-width image1))
                  (min-height (image-height image1))))

(define timer 
    (new timer%
         (notify-callback
          (lambda()
            (send (send mcan get-dc)
                  draw-bitmap image2 0 0)))))

(send my-frame show #t)
(send timer start 1000)

第三种方法是使用this postRacket discussion list中所述的sleep\yield