【问题标题】:Set and Reset of System Variables - AutoCAD LISP设置和重置系统变量 - AutoCAD LISP
【发布时间】:2019-11-19 03:18:25
【问题描述】:

我正在尝试在 AutoCAD 中非常容易地绘制接线图,除了我的预编程按钮之外,几乎没有任何按钮按下。

其中一个涉及 LISP,它不能很好地设置系统变量,然后将它们重置为以前的状态。该程序似乎执行了预期的功能,但没有达到预期的结果。

一旦我的PLINE 命令启动,变量就会被重置。我需要PLINE 来启动、完成,然后然后重置变量。

我尝试在 LISP 的命令中以及通过 (setvar (getvar ...)) 命令设置 OrthoMode 和 SnapMode。

(defun varget ()
    (setq lis '("orthomode" "snapmode"))
    (setq var (mapcar 'getvar lis))
    (setq var1 '(1 1))
    (setq no 0)
    (repeat (length lis)
        (setvar (nth no lis) (nth no var1))
        (setq no (1+ no))
    )
    (princ)
 )

(defun varset ()
    (setq no 0)
    (repeat (length lis)
        (setvar (nth no lis) (nth no var))
        (setq no (1+ no))
    )
(princ)
)

(princ)

(defun C:wire ()
(progn
(varget)
(setq prevlayer (getvar "clayer"))
(setq P (getstring "Audio(A)/Video(V)/Comm(CO)/Coax(R)/Control(C)/(N)etwork/(P)ower:"))
(IF (= P "V")(command "-LAYER" "M" "VIDEO" "C" "150" "" "" "PLINE" PAUSE))
(IF (= P "A")(command "-LAYER" "M" "AUDIO" "C" "94" "" "" "PLINE" PAUSE))
(IF (= P "CO")(command "-LAYER" "M" "COMM" "C" "206" "" "" "PLINE" PAUSE))
(IF (= P "R")(command "-LAYER" "M" "COAX" "C" "44" "" "" "PLINE" PAUSE))
(IF (= P "C")(command "-LAYER" "M" "CONTROL" "C" "10" "" "" "PLINE" PAUSE))
(IF (= P "N")(command "-LAYER" "M" "NETWORK" "C" "210" "" "" "PLINE" PAUSE))
(IF (= P "P")(command "-LAYER" "M" "POWER" "C" "7" "" "" "PLINE" PAUSE))
(setvar "clayer" prevlayer)
(varset)
(princ)
);Progn
);defun

没有错误消息。

我希望在执行PLINE 命令之后重置变量。

【问题讨论】:

    标签: lisp autocad autocad-plugin autolisp


    【解决方案1】:

    您的代码的问题在于,在尝试重置系统变量和完成程序评估之前,您只是暂停了单个用户输入。

    相反,在继续程序评估之前,您需要使用循环来不断暂停用户输入。

    例如:

    ;; Define function, declare local symbols
    (defun c:wire ( / col lay opt val var )
    
        ;; System variables to be modified within the program
        (setq var '(clayer orthomode snapmode cmdecho)
        ;; Retrieve current sys var values
              val  (mapcar 'getvar var)                
        ) ;; end setq
    
        ;; Predefine the getkword options
        (initget "Audio Video COmm R Control Network Power")
        ;; Prompt the user for input, default to "Audio" on null input
        (setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))
    
        ;; Define the layer & colour based on the option returned
        (cond
            (   (= opt "Audio")   (setq lay "AUDIO"    col  94))
            (   (= opt "Video")   (setq lay "VIDEO"    col 150))
            (   (= opt "COmm")    (setq lay "COMM"     col 206))
            (   (= opt "R")       (setq lay "COAX"     col  44))
            (   (= opt "Control") (setq lay "CONTROL"  col  10))
            (   (= opt "Network") (setq lay "NETWORK"  col 210))
            (   (= opt "Power")   (setq lay "POWER"    col   7))
        ) ;; end cond
    
        ;; Suppress command-line output for the -LAYER command
        (setvar 'cmdecho 0)
        ;; Create & set the layer & layer colour
        (command "_.-layer" "_M" lay "_C" col "" "")
    
        ;; Set everything except the first sys var
        (mapcar 'setvar (cdr var) '(1 1 1))
        ;; Initiate the PLINE command
        (command "_.pline")
        ;; Continuously pause for user input
        (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))
    
        ;; Reset system variables
        (mapcar 'setvar var val)
    
        ;; Suppress the value returned by the last evaluated expression
        (princ) 
    ) ;; end defun
    

    注意几点:

    • 始终声明局部变量以避免与文档命名空间中的同名变量发生冲突。请参阅我的教程here,了解有关如何以及为什么这样做的更多信息。

    • 使用getkword 代替getstring 来控制和验证用户的输入。

    • 使用"\\" 代替pause 符号,因为pause 符号是一个不受保护的全局变量,很容易在您的程序之外不经意地重新定义,从而导致您的程序中断。由于pause 符号的计算结果为"\\",您也可以使用文字反斜杠。

    作为扩展,您可能还需要考虑实现一个本地错误处理程序来处理用户在评估程序期间不可避免地按下 Esc (否则在这种情况下系统变量不会被重置) )。我在我的教程 here 中描述了如何做到这一点。

    这是一个基本示例,展示了包含本地错误处理程序:

    ;; Define function, declare local symbols
    (defun c:wire ( / *error* col lay opt val var )
    
        ;; Define local error handler
        (defun *error* ( msg )
            ;; Reset system variables
            (mapcar 'setvar var val)
            ;; Suppress the output of standard cancellation messages
            (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
                ;; Print critical errors
                (princ (strcat "\nError: " msg))
            ) ;; end if
            (princ) ;; Suppress the value returned by the last evaluated expression
        ) ;; end defun
    
        ;; System variables to be modified within the program
        (setq var '(clayer orthomode snapmode cmdecho)
        ;; Retrieve current sys var values
              val  (mapcar 'getvar var)                
        ) ;; end setq
    
        ;; Predefine the getkword options
        (initget "Audio Video COmm R Control Network Power")
        ;; Prompt the user for input, default to "Audio" on null input
        (setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))
    
        ;; Define the layer & colour based on the option returned
        (cond
            (   (= opt "Audio")   (setq lay "AUDIO"    col  94))
            (   (= opt "Video")   (setq lay "VIDEO"    col 150))
            (   (= opt "COmm")    (setq lay "COMM"     col 206))
            (   (= opt "R")       (setq lay "COAX"     col  44))
            (   (= opt "Control") (setq lay "CONTROL"  col  10))
            (   (= opt "Network") (setq lay "NETWORK"  col 210))
            (   (= opt "Power")   (setq lay "POWER"    col   7))
        ) ;; end cond
    
        ;; Suppress command-line output for the -LAYER command
        (setvar 'cmdecho 0)
        ;; Create & set the layer & layer colour
        (command "_.-layer" "_M" lay "_C" col "" "")
    
        ;; Set everything except the first sys var
        (mapcar 'setvar (cdr var) '(1 1 1))
        ;; Initiate the PLINE command
        (command "_.pline")
        ;; Continuously pause for user input
        (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))
    
        ;; Reset system variables
        (mapcar 'setvar var val)
    
        ;; Suppress the value returned by the last evaluated expression
        (princ) 
    ) ;; end defun
    

    【讨论】:

    • 太棒了,非常感谢!在玩弄更多代码时,我想出了在 IF 语句之后添加 (while (> (“cmdactive”) 0) pause) 并且它起作用了。不过,感谢这些指针。我肯定会将它们实施到我未来的计划中。
    猜你喜欢
    • 2016-03-31
    • 1970-01-01
    • 2016-09-29
    • 2014-10-25
    • 1970-01-01
    • 2021-04-16
    • 2017-07-02
    • 2016-11-26
    • 2020-02-08
    相关资源
    最近更新 更多