Racket 编程

3 部分 · 应用开发实战

GUI 绘图与事件

GUI 绘图与事件

深入画布绘图、自定义控件和事件驱动编程。

自定义画布

#lang racket/gui

(define my-canvas%
  (class canvas%
    (inherit get-dc)
    (define/override (on-event event)
      (when (send event button-down?)
        (define dc (get-dc))
        (define x (send event get-x))
        (define y (send event get-y))
        (send dc set-brush
              (make-object color% (random 256) (random 256) (random 256))
              'solid)
        (send dc draw-ellipse (- x 10) (- y 10) 20 20)))
    (super-new)))

绘图基础

(define (draw-scene canvas dc)
  ;; 设置画笔和画刷
  (send dc set-pen "black" 2 'solid)
  (send dc set-brush "lightblue" 'solid)

  ;; 绘制基本形状
  (send dc draw-rectangle 50 50 200 100)
  (send dc draw-ellipse 100 200 80 80)
  (send dc draw-line 0 0 300 300)

  ;; 绘制文本
  (send dc set-font (make-object font% 16 'default))
  (send dc draw-text "Hello, Racket GUI!" 60 70))

自定义控件

;; 自定义带标签的输入框
(define labeled-input%
  (class horizontal-panel%
    (init-field label-text)
    (super-new)
    (new message%
         [parent this]
         [label label-text]
         [min-width 80])
    (define input
      (new text-field%
           [parent this]
           [label #f]
           [min-width 200]))
    (define/public (get-value)
      (send input get-value))))

事件驱动模式

;; 定时器动画
(define frame (new frame% [label "Animation"] [width 400] [height 400]))
(define canvas (new canvas% [parent frame]))

(define x 0)
(define direction 1)

(define timer
  (new timer%
       [interval 16]  ; ~60 FPS
       [notify-callback
        (lambda ()
          (set! x (+ x (* 3 direction)))
          (when (or (> x 380) (< x 0))
            (set! direction (- direction)))
          (send canvas refresh-now))]))

(send frame show #t)

小结

GUI 编程的核心是绘图和事件处理。掌握画布、自定义控件和定时器,你就能创建交互丰富的桌面应用。