如何使用Lisp创建GUI:DrScheme或Common Lisp

时间:2011-12-06 15:18:15

标签: user-interface lisp racket

或者创建GUI需要做的基本工作。我知道基本的组件 GUI,但从哪里开始。我只是一个自学者,我正在阅读本书末尾的“如何设计程序”(HtDP),作者认为GUI和CGI计算机网络的知识需要成为程序员。最后两个的信息很容易找到。但似乎很少有人谈论如何创建GUI。我想也许在设计计算机程序的过程中它太“低”,很少有人关心。

4 个答案:

答案 0 :(得分:10)

DrRacket中的GUI编程文档(DrScheme当前版本的名称)位于:http://docs.racket-lang.org/gui/index.html

由于您正在阅读HTDP,这可能是您现在最好的选择。

答案 1 :(得分:9)

  • 如果你想在Common Lisp中创建简单的GUI,那就最好了 在我看来,选择是LTK,它是一个高级接口 Tcl / Tk脚本库
  • 还有很多其他选择,但它们需要一些 你想要实现的目标。如果你想使用 其中一个广泛的GUI工具包(GTK或Qt)有CL-GTK2 和CommonQt。但是你必须首先理解这些,如何 工具包工作
  • LispWorks提供了一个非常复杂的GUI构建器库CAPI, 这是跨平台的
  • 在Mac上ClozureCL有很好的Cocoa bindings
  • 最后,有一个完整的原生CL解决方案用于GUI - McCLIM - 这非常灵活,但非常复杂

另外,如果你想从理论的角度理解GUI并研究它,你应该学习各种GUI模式,比如MVC,Model2,MVVM等。我不知道任何GUI框架Lisp,实现这样的模式,所以做这样的项目可能是一个有趣的学习经历...

答案 2 :(得分:7)

有一个轻量级库,可以通过2htdp / universe编写简单的图形程序。请参阅:How to Design Worlds

基本思想是现代图形库是高度事件驱动的:您通过响应事件与外部世界进行交互。如果仔细观察它,Universe库就是MVC模型的一个实现:世界是“模型”,绘制“视图”,所有其他事件处理程序是“控制器”。

如果您想在Racket中使用更多低级元素,可以使用racket / gui库。这些参考文档在The Racket Graphical Interface Toolkit中。这是一个使用库的小例子:

#lang racket

(require racket/gui/base
         2htdp/image
         (only-in mrlib/image-core render-image))

;; The state of our program is a number.
(define state 0)

;; On a timer tick, increment the state, and refresh the canvas.
;; tick!: -> void
(define (tick!)
  (set! state (add1 state))
  (send THE-CANVAS refresh))


;; When a canvas paints itself, use the following:
;; paint: canvas% dc<%> -> void
(define (paint! a-canvas my-drawing-context)
  (define my-new-scene (text (format "I see: ~a" state) 20 'black))
  ;; Note: we force the canvas to be of a particular width and height here:
  (send a-canvas min-client-width (image-width my-new-scene))
  (send a-canvas min-client-height (image-height my-new-scene))
  (render-image my-new-scene my-drawing-context 0 0))


;; Here, we initialize our graphical application.  We create a window frame...
;; THE-FRAME: frame%
(define THE-FRAME (new (class frame%
                         (super-new)
                         ;; When we close the frame, shut down everything.
                         (define/augment (on-close)
                           (custodian-shutdown-all (current-custodian))))
                       [label "Example"]))


;; and add a canvas into it.
;; THE-CANVAS: canvas%
(define THE-CANVAS (new (class canvas%
                          (super-new)

                          ;; We define a key handler.  Let's have it so it
                          ;; resets the counter on a key press
                          (define/override (on-char key-event)
                            (when (eq? (send key-event get-key-code) 'release)
                              (set! state 0)
                              (send THE-CANVAS refresh))))
                        [parent THE-FRAME]
                        [paint-callback paint!]))

;; We get the frame to show on screen:
(send THE-FRAME show #t)

;; Finally, we set up a timer that will call tick! on every second.
(define THE-TIMER (new timer% 
                       [notify-callback tick!]
                       [interval 1000]))

答案 3 :(得分:2)