While循环中的While循环
我有一个快速的问题,关于编写代码的最有效方式是什么,该代码将不断向用户询问源对象和目标对象。我知道如何为以下单个选择编写此代码:我的问题是如何有效地为两个对象编写此代码(即,您将获得两个对象的错过提示或无效对象,然后在选择每个对象后,一个代码将运行,然后重复,直到用户点击escape或空格键。我已经编写了所有代码,只是这个while循环我无法正常工作。 可能有2个defuns,但使用和来确认两者都符合标准。 请看一下李的代码,这可能会有所帮助。我经常用它 我通常这样做:
(defun *error* ( msg ) ; sometimes we need an error handler, for example the osmode variable
(if osm (setvar 'osmode osm))
(if (not (member msg '("Function cancelled" "quit / exit abort")))
(princ (strcat "\nError: " msg))
)
(princ)
)
(setq osm (getvar 'osmode))
(setvar 'osmode 0)
(while T ; start the overall loop
(setvar 'errno 0)
(while ; source object loop
(not
(and
(setq ent1 (car (entsel "\nSelect source object: ")))
(eq (cdr (assoc 0 (setq elist1 (entget ent1)))) "INSERT") ; optional filter
)
)
(if (or (= (getvar 'errno) 7) (null ent1) ) (princ "\nYou missed try again!"))
)
(while ; destination object loop
(not
(and
(setq ent2 (car (entsel "\nSelect destination object: ")))
(eq (cdr (assoc 0 (setq elist2 (entget ent2)))) "INSERT") ; optional filter
)
)
(if (or (= (getvar 'errno) 7) (null ent2) ) (princ "\nYou missed try again!"))
)
(progn
; (we got the source and destination objects, do the rest of your stuff here)
)
) ; end the overall loop
如果我理解正确,有很多方法可以处理这些类型的选择:
(defun c:pick2 (/ s1 e1 s2 e2)
(and
(princ "\nSelect Source INSERT")
(setq s1 (ssget (list (cons 0 "INSERT"))))
(= (sslength s1) 1)
(setq e1 (ssname s1 0)))
(redraw e1 3)
(while
(and
(princ "\nSelect 1 Target INSERT")
(setq s2 (ssget (list (cons 0 "INSERT"))))
(= (sslength s1) 1)
(setq e2 (ssname s2 0))
(not (eq e1 e2)))
(prin1 e2)
)
(redraw)
(prin1))
将(prin1 e2)调用替换为您想要完成的操作。
-大卫 Grr,这是另一个while循环的酷用法!我也在想如何通过按空格键退出,但我想不出来。我试着做一个条件,如果实体为null,那么我把它设为nil,但这不起作用。你能想到怎么做吗?David,我以前没有见过使用while循环的ssget,这非常灵活(不幸的是,我必须使用nentsel,因为我从外部参照中的对象获取信息)。 我建议将选择操作划分为一个单独的功能,例如:
(defun c:test ( / des prd src )
(setq prd
'(lambda ( x )
(wcmatch
(cdr (assoc 0 (entget x)))
"LINE,ARC,CIRCLE,LWPOLYLINE,POLYLINE,RAY,XLINE,AECC_FEATURE_LINE"
)
)
)
(if
(and
(setq src (selectif "\nSelect source object: " prd))
(setq des (selectif "\nSelect destination object: " prd))
)
(princ "\nDo stuff.")
)
(princ)
)
(defun selectif ( msg prd / ent )
(while
(progn (setq ent (car (entsel msg)))
(cond
( (= 7 (getvar 'errno))
(princ "\nMissed, try again.")
)
( (not ent) nil)
( (not (apply prd (list ent)))
(princ "\nInvalid object selected.")
)
)
)
)
ent
) 李,非常感谢你的帮助!我现在遇到的问题是添加了另一个while循环,该循环将一直运行,直到空格键被击中或逃脱。例如,用户将选择源对象,然后选择目标对象,然后选择源对象,然后选择目标。。。直到他们做了他们想做的一切,然后他们就会击中空间或逃跑。 因此,我最终通过以下方式实现了这一点:
(while
(and
(setq sent (selectif "\nSelect source object: "))
(setq dent (selectif "\nSelect destination object: "))
)
;...Rest of code像这样使用and函数有什么问题吗? 通过阅读本文,我认为您必须使用其他方法-提示用户在循环中不断选择源和目标对象,并在这样做的同时构建一个assoc列表,如下所示:
(<source ent1> . <destination ent1>) (<source ent2> . <destination ent2>) ... (<source entN> . <destination entN>)
然后为列表中的每一对做你的秘密工作。
不幸的是,我不知道如何编写这个代码(但我对此很感兴趣,因为我脑海中也有类似的想法)。
页:
[1]
2