Problems with ltk (common lisp)

2019-06-17 14:28发布

问题:

I installed ltk to Steel Bank Common Lisp with asdf-install, but I can't even start using it V_V. The code below is the simplest example in the documentation, and is copied almost verbatim.


(asdf:operate 'asdf:load-op :ltk)

(defun hello-1()
  (with-ltk ()
   (let ((b (make-instance 'button
                           :master nil
                           :text "Press Me"
                           :command (lambda ()
                                      (format t "Hello World!~&")))))
     (pack b))))
(hello-1)

This is the error message I get from sbcl:


> ; in: LAMBDA NIL
;     (PACK B)
; 
; caught STYLE-WARNING:
;   undefined function: PACK

;     (WITH-LTK NIL
;      (LET ((B (MAKE-INSTANCE 'BUTTON :MASTER NIL :TEXT "Press Me" :COMMAND #)))
;        (PACK B)))
; 
; caught STYLE-WARNING:
;   undefined function: WITH-LTK
; 
; compilation unit finished
;   Undefined functions:
;     PACK WITH-LTK
;   caught 2 STYLE-WARNING conditions

debugger invoked on a SIMPLE-ERROR in thread #<THREAD "initial thread" RUNNING {1002A57B61}>:
  There is no class named BUTTON.

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-PCL::FIND-CLASS-FROM-CELL BUTTON NIL T)

回答1:

You have to import the symbols into the package you want it to work in.

The generic "user" package is cl-user, and a "virgin" image will put you there. In order to import the (exported) symbols from another package, issue (use-package :another-package). Example on the REPL:

(asdf:load-system :ltk)
(use-package :ltk)

Sometimes one wants to use symbols that are not imported. You can then prefix them with the package, like bar:foo, where bar is the package name and foo the symbol.

When working on a real system, you will usually define one or more packages for it. This is done through defpackage, which you can tell what other packages to import directly:

(defpackage #:my-app
  (:use :cl
        :ltk))

Then, you need to switch to that package:

(in-package #:my-app)

When setting up a more complicated system with several interdependent files, a system definition facility becomes worthwhile. The currently most widely used is ASDF, although a handful of alternatives exist.



回答2:

ASDF doesn't load a package into the COMMON-LISP-USER package. As a result, WITH-LTK isn't defined in your current package, so you need to do this:

(asdf:oos 'asdf:load-op :ltk)
(in-package :ltk)
;put your function here