第 3 部分 · 应用开发实战
GUI 开发入门
GUI 开发入门
使用 racket/gui 库创建跨平台的桌面应用程序。
第一个窗口
#lang racket/gui ;; 创建主窗口 (define frame (new frame% [label "我的第一个 Racket GUI"] [width 400] [height 300])) ;; 创建消息面板 (define msg (new message% [parent frame] [label "Hello, Racket GUI!"] [auto-resize #t])) ;; 显示窗口 (send frame show #t)
运行这段代码,你会看到一个带有标题和文本的窗口。
添加交互控件
#lang racket/gui (define frame (new frame% [label "交互示例"] [width 400] [height 200])) ;; 文本输入 (define input (new text-field% [parent frame] [label "输入名字:"])) ;; 按钮 (define btn (new button% [parent frame] [label "打招呼"] [callback (lambda (button event) (define name (send input get-value)) (message-box "问候" (format "你好, ~a!" name) frame))])) (send frame show #t)
布局管理
使用水平和垂直面板组织控件:
#lang racket/gui (define frame (new frame% [label "布局示例"] [width 500] [height 400])) ;; 垂直面板 (define vpanel (new vertical-panel% [parent frame] [alignment '(center center)])) ;; 水平面板 (define hpanel (new horizontal-panel% [parent vpanel] [alignment '(center center)])) ;; 在水平面板中添加按钮 (new button% [parent hpanel] [label "按钮 1"]) (new button% [parent hpanel] [label "按钮 2"]) (new button% [parent hpanel] [label "按钮 3"]) ;; 下方添加一个画布 (define canvas (new canvas% [parent vpanel] [min-height 200] [paint-callback (lambda (canvas dc) (send dc set-brush "blue" 'solid) (send dc draw-rectangle 50 50 100 100))])) (send frame show #t)
画布与绘图
#lang racket/gui (define frame (new frame% [label "绘图示例"] [width 600] [height 400])) (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 canvas (new my-canvas% [parent frame] [paint-callback (lambda (canvas dc) (send dc set-background "white") (send dc clear))])) (send frame show #t)
点击画布任意位置,会绘制一个随机颜色的圆形。
菜单和对话框
#lang racket/gui (define frame (new frame% [label "菜单示例"] [width 400] [height 300])) ;; 菜单栏 (define menu-bar (new menu-bar% [parent frame])) ;; 文件菜单 (define file-menu (new menu% [label "文件"] [parent menu-bar])) (new menu-item% [label "打开..."] [parent file-menu] [callback (lambda (m e) (define path (get-file)) (when path (printf "选择了文件: ~a\n" path)))]) (new separator-menu-item% [parent file-menu]) (new menu-item% [label "退出"] [parent file-menu] [callback (lambda (m e) (send frame show #f))]) ;; 帮助菜单 (define help-menu (new menu% [label "帮助"] [parent menu-bar])) (new menu-item% [label "关于"] [parent help-menu] [callback (lambda (m e) (message-box "关于" "Racket GUI 示例程序 v1.0"))]) (send frame show #t)
事件处理模型
Racket GUI 使用回调函数处理事件:
| 事件类型 | 触发条件 |
|---|---|
| button% | 按钮点击 |
| text-field% | 文本变化 |
| canvas% | 鼠标/键盘交互 |
| timer% | 定时触发 |
;; 定时器示例 (define timer (new timer% [interval 1000] ; 每秒触发一次 [notify-callback (lambda () (printf "Tick: ~a\n" (current-seconds)))]))
打包应用
使用 raco exe 将 Racket GUI 程序打包为可执行文件:
# 创建可执行文件
raco exe --gui my-app.rkt
# 生成独立分发的目录
raco dist my-app-dist my-app.exe
这样生成的应用可以在没有 Racket 运行时的机器上运行。