Урок 5. Пример программы LISP с диалоговым окном.

В этом уроке мы рассмотрим, как из программы LISP управлять диалоговым окном.

В качестве примера мы будем использовать диалоговое окно созданное в предыдущем уроке: «Диалоговое окно».

В конце статьи смотрите видео к этому уроку.

И сразу начнем с программного кода, который управляет диалоговым окном.

См. Рис. 1.

Рис. 1. «Программный код управления диалоговым окном.»

Управление диалоговым окном из LISP программы происходит в несколько этапов:

Загрузка файла диалогового окна

Сначала необходимо загрузить DCL-файл, содержащий нужный диалог.

Для этого используется функция (load_dialog "mp_paral.dcl"), где
load_dialog – функция загрузки файла диалога.
"mp_paral.dcl" – имя загружаемого файла диалога.

Если диалоговое окно загрузится, то данная функция вернёт порядковый номер загруженного DCL-файла в данном сеансе работы с системой AutoCAD.

При помощи оператора присвоения setq запоминаем этот номер в переменной dcl_id.

(setq dcl_id (load_dialog "mp_paral.dcl")) .

Если диалоговое окно не загрузится, то функция вернет отрицательное целое число.

Если имя файла в аргументе указано без полного пути, то система AutoCAD пытается найти файл в папках  поддержки, где находятся вспомогательные файлы.

Добавляем путь доступа к вспомогательным файлам.

Чтобы не писать полный путь к нашему диалоговому окну, давайте добавим путь к нашей папке «D:\MyLisp» в пути доступа к вспомогательным файлам AutoCAD. Сделаем из нее папку поддержки.

Для этого щелкаем по «Кнопке приложения» и в открывшимся окне по кнопке «Параметры». См. Рис. 2.

Рис. 2.  Кнопка приложения

Откроется окно «Настройка». См. Рис 3.

Рис. 3. «Добавление пути доступа к вспомогательным файлам»

В нем переходим на вкладку «Файлы».

Щелкаем на [+] напротив пункта «Путь доступа к вспомогательным файлам».

Далее нажимаем на кнопку «Добавить». Затем на кнопку «Обзор…». Откроется окно «Обзор папок».

Находим папку «D:\MyLisp» и нажимаем ОК.

В путях доступа к вспомогательных файлам появится новая строка «D:\MyLisp».

См. Рис. 4

Рис. 3. «Путь доступа к вспомогательным файлам»

Нажимаем ОК. Теперь AutoCAD знает, где искать наш файл и вместо полного пути к нем, достаточно написать только его имя.

Открытие диалогового окна и проверка существования диалога.

Функция (new_dialog "mp_paral" dcl_id)  открываем диалоговое окно.
"mp_paral" – имя диалога, которое задано внутри файла  "mp_paral.dcl”.
dcl_id – порядковый номер загружаемого файла диалога.

Функция открываем диалоговое окно и возвращает T (True), если диалог с таким именем в этом файле есть.

И возвращает nil если диалог не найден.

Давайте для лучшего понимания в строчке

 (if (not (new_dialog "mp_paral" dcl_id))(exit))

заменим функцию (new_dialog «mp_paral» dcl_id)  возвращаемым значением Т.

Получится (if (not T)(exit)) – если не Т выйти. Иными словами, если диалоговое окно не открылось завершить выполнение программы.

Если все прошло удачно, диалоговое окно откроется в рабочем окне AutoCAD. См. Рис. 5.

Рис. 5.    Диалоговое окно DCL

LISP программа встанет на паузу и будет ожидать действия пользователя.

Вводим значения в поля «Длина», «Ширина», «Высота» и нажимаем на одну из двух кнопок. (ОК или Отмена). AutoCAD вернется в LISP программу.

Описание действий при нажатии кнопок и закрытие диалогового окна.

Для описание действий, которые выполнить программа при нажатии на кнопки используется функция action_tile. В общем виде она выглядит так:

(action_tile "код" "LISP-выражение")
"код" – код выбранной кнопки.
“LISP-выражение", которое необходимо выполнить.

Таким образом следующее выражение

(action_tile "accept" "(raz_paral) (done_dialog 1)") мы можем прочитать так:
При нажатии на кнопку «ОК» ("accept" – код кнопки ОК) выполнить 
пользовательскую функцию (raz_paral) и функцию (done_dialog 1).

О пользовательской функции (raz_paral) мы поговорим ниже.

Функция (done_dialog 1) – закрывает диалоговое окно и передает числовое значение, которое можно будет прочитать функцией (start_dialog)

Следующее выражение

(action_tile "cancel" "(done_dialog 0)") можно прочитать так:
Если нажата кнопка «Отмена» ("cancel" – код кнопки «Отмена) закрыть 
диалоговое окно со значением «0»

В следующей строчке

(setq ddi (start_dialog))

(start_dialog) считывает с каким числовым значением было закрыто диалоговое окно

Setq – присваивает это значение переменной ddi.

Выгрузка файла диалогового окна

Функция (unload_dialog dcl_id) – выгружает диалоговое окно с порядковым номером dcl_id.

Функция defun.

Для создания функций пользователя предназначена функция defun. В общем виде она выглядит так:

(defun <name> ( [<аргументы>] [/ <рабочие>])
    <выражения>
)

, где

<name> - имя новой функции.
<аргументы> - символы, которые используются в качестве аргументов новой функции.
<рабочие> - символы, которые используются в качестве временных, рабочих переменных.
<выражения> - любая последовательность выражений, которые  используют
как аргументы и рабочие переменные, так и другие функции.
[ ] – квадратные скобки указывают, что этот элемент не является обязательным

Пользовательская функция (raz_paral) (размеры параллелепипеда).

Программный код создающий функцию  (raz_paral) показан, на Рис. 6.

Рис. 6.  «Пользовательская функция raz_paral»

Функция (get_tile «eb_Dl«) – считывает в диалоговом окне содержимое поля с кодом eb_Dl. Возвращает строчное значение ( если в поле стояло 100, то возвращается «100»).

Для того, чтобы преобразовать строку в целое число используют функцию (atoi <строка>)

Пример (atoi "100") – возвращает 100.

Таким образом, строка

(setq Dl (atoi (get_tile "eb_Dl")))

Считывает содержимое из поля «Длина» (код поля eb_Dl), преобразует его в целое число и присваивает его (при помощи функции setq) переменной Dl.

Аналогично, строка

(setq Sh (atoi (get_tile "eb_Sh")))

Считывает содержимое из поля «Ширина» и запоминает его в переменной Sh.

А строка

(setq Hi (atoi (get_tile "eb_Hi")))

Считывает содержимое из поля «Высота» и запоминает его в переменной Hi.

Функция (raz_paral) – не содержит аргументов и временных рабочих переменных. Если переменные Dl, Sh, Hi указать в качестве рабочих, то по окончании выполнения функции значения переменных будут стерты из оперативной памяти. А нам нужно, чтобы после окончания функции (raz_paral) эти переменные сохранили свои значения.

После того, как функция создана, её можно вызывать в любом месте программы набрав (raz_paral).

Пользовательская функция (mp_kub Dl Sh Hi).

Давайте, преобразуем программу, созданную в уроке «Пример простой программы LISP» в пользовательскую функцию. См. Рис. 7.

Рис. 7. «Пользовательская функция mp_kub»

Для этого удаляем «с:»

Добавляем аргументы Dl Hi Sh.

И расставляем аргументы в программе вместо числа 200, как это показано на Рис.7.

В результате у нас получится пользовательская функция, показанная на Рис. 8.

Рис. 7. «Пользовательская функция mp_kub»

После выполнения функции mp_kub значения переменных  р1 р2 р3 р4 р5 р6 р7 р8 нам не нужны. И чтобы они не хранились в оперативной памяти, добавляем их в качестве временных рабочих переменных.

Для того, чтобы вызвать эту функцию нужно набрать

(mp_kub Dl Sh Hi), где
mp_kub – имя функции.
Dl Sh Hi – ее аргументы.

Общая программа LISP с диалоговым окном.

Общая программа LISP с диалоговым окном будет выглядеть как на Рис. 9.

Рис. 9. » Общая программа»

 Программный код программы mp_paral:

(DEFUN c:mp_paral (/ dcl_id nub Dl Sh Hi) ; начало функции mp_paral
  ;--------------------- финкция mp_kub --------------------------------------
  (DEFUN mp_kub   (Dl Sh Hi / p1 p2 p3 p4 p5 p6 p7 p8) ; начало функции mp_kub
    (setq p1 (getpoint "\nУкажите базовую точку : ")) ; запрос координат базовой точки
    (setq p2 (polar p1 0 Dl))              ; определение координат точки р2
    (setq p3 (polar p2 (/ pi 2) Hi))      ; определение координат точки р3
    (setq p4 (polar p3 pi Dl))             ; определение координат точки р4
    (setq p5 (polar p1 (/ pi 4) Sh))    ; определение координат точки р5
    (setq p6 (polar p2 (/ pi 4) Sh))    ; определение координат точки р6
    (setq p7 (polar p3 (/ pi 4) Sh))    ; определение координат точки р7
    (setq p8 (polar p4 (/ pi 4) Sh))    ; определение координат точки р8
    (setq osm (getvar "osmode"))     ; запоминаем привязки пользователя
    (setvar "osmode" 0)                               ; отключаем привязки
    (command "_line" p1 p2 p3 p4 p1 "")     ; рисуем передную грань
    (command "_line" p5 p6 p7 p8 p5 "")     ; рисуем задную грань
    (command "_line" p1 p5 "")                    ; рисуем линию 1-5
    (command "_line" p2 p6 "")                    ; рисуем линию 2-6
    (command "_line" p3 p7 "")                    ; рисуем линию 3-7
    (command "_line" p4 p8 "")                    ; рисуем линию 4-8
    (setvar "osmode" osm)                          ; возвращаем привязки пользователя
  ) ; окончание функции mp_kub
  ;-----------------------------------------------------------------------------
  ;-------------------- финкция raz_paral --------------------------------------
  (defun raz_paral ()
    (setq Dl (atoi (get_tile "eb_Dl")))
    (setq Sh (atoi (get_tile "eb_Sh")))
    (setq Hi (atoi (get_tile "eb_Hi")))
  )
  ;-----------------------------------------------------------------------------
  ;-----------------------------------------------------------------------------
  ;------------------------  Диалоговое окно  ----------------------------
  ;-----------------------------------------------------------------------------
  (setq dcl_id (load_dialog "mp_paral.dcl")) ; загружаем диалог (файл DCL)
  (if (not (new_dialog "mp_paral" dcl_id))(exit))  ; проверка существования диалога
  (action_tile "accept" "(raz_paral) (done_dialog 1)")  ; Если нажата кнопка "аccept"
  (action_tile "cancel" "(done_dialog 0)") ; Если нажата кнопка "cancel"
  (setq ddi (start_dialog))
  (unload_dialog dcl_id) ; выгрузить Диалоговое окно
  ;-----------------------------------------------------------------------------
  (if (= ddi 1) (mp_kub Dl Sh Hi))
  (princ)
) ; окончание функции mp_paral

Скачать диалоговое окно Mp_paral.dcl (Размер файла: 392 bytes)

Скачать программу Mp_paral.lsp (Размер файла: 781 bytes)

 

Первая строка

(defun c: mp_paral (/ dcl_id nub Dl Sh Hi)

Создаёт функцию пользователя с именем «mp_paral».

Префикс «с:» означает, что эту функцию можно будет использовать как стандартную команду AutoCAD.

Достаточно ввести имя в командную строку AutoCADа.

(/ dcl_id nub Dl Sh Hi) – временные рабочие переменные, которые используются в программе.

Далее, идёт создание пользовательской функции mp_kub (рассмотрено выше).

Затем, создание пользовательской функции raz_paral (рассмотрено выше).

После этого программа осуществляет управление диалоговым окном (рассмотрено выше).

Строка:

(if (= ddi 1) (mp_kub Dl Sh Hi)) читается следующем образом:

Если переменная ddi=1 выполнить функцию (mp_kub Dl Sh Hi)

Переменная ddi=1, если пользователь, в диалоговом окне, нажал на кнопку «ОК».

Если пользователь нажал на кнопку «Отмена», переменная ddi=0 и  функция (mp_kub Dl Sh Hi) выполнена не будет.

Функция (princ) осуществляет тихий выход.

Последняя «)» — означает окончание функции mp_paral.

Загрузка и запуск программы mp_paral.

Для того, чтобы проверить работу программы:

Запускаем  AutoCAD.

Далее запускаем редактор Visual LISP, набрав командной строке VLISP.

Создаем новый файл Рис. 10.

Рис. 10.  «Создание нового файла»

Набираем в нем текст программы или копируем с сайта.

Сохраняем файл в папке «D:/MyLisp» под именем «mp_paral».

Далее загружаем программу и переходим в AutoCAD. См. Рис. 11

Рис. 11. «Загрузка программы»

В командной строке вводим mp_paral и нажимаем <Enter>. См. Рис. 12.

Рис. 12.  «Командная строка»

Откроется диалоговое окно «Параллелепипед». См. Рис 13.

Рис. 13. «Диалоговое окно»

В нем заполняем поля «Длина», «Ширина», «Высота» и нажимаем на кнопку ОК.

В командной строке появится сообщение: «Укажите базовую точку :».  Щелкните в любой точки рабочего окна AutoCAD и он нарисует Параллелепипед. См. Рис. 14.

Рис. 14.  «Параллелепипед»

Смотрите видео к этому уроку:

Таким образом, в этой статье мы рассмотрели пример создания программы LISP c диалогового окна.

Рассмотрели:

  • Как управлять диалоговым окном из программы LISP.
  • Как добавлять путь доступа к вспомогательным файлам AutoCAD.
  • Как создавать и использовать пользовательские функции.

Пишите в комментариях:

все ли у вас получилось?;

трудно ли было выполнить этот урок?;

где у вас возникли трудности?

Я с удовольствием отвечу на все ваши комментарии.

Если вы хотите получать новости с моего сайта. Оформляйте подписку.

До новых встреч.

 «Автор: Михаил Орлов»

Google

Также на эту тему Вы можете почитать:

Михаил Орлов

View Comments

  • Спасибо. Прочитал с интересом, и вообще полезный у Вас блог

  • Спасибо, всё докладно. У меня такой вопрос: как сохранить введенные в окне пользователем значения в файл, чтобы в следующем сеансе работы автокада, при вызове окна, там уже были данные прошлого сеанса? Запись в текстовый файл (write-line) понятна, а как-же в DCL написать чтобы считывались файлы с этого .txt (для элемента "value"). Или это сделать другим способом?

    • Считываете из текстового файла нужное значение (read-line) и при помощи функции (set_tile) присваиваете его полю диалогового окна.
      Здесь показан пример как хранить данные в пространстве модели:
      http://acad-prog.ru/avtomatizatsiya-proektirovaniya/#pvoz

  • Здравствуйте, пытаюсь написать программу по вашему примеру) но, у меня возникают ошибки, не могу разобраться, где именно) не могли бы вы помочь мне?)

  • у меня всё получилось)) спасибо вам огромное)

    остался вопрос, можно ли включить в программу массив по траектории? пытаюсь найти в других источниках, но однозначного ответа найти не получается) не могли бы вы помочь решить этот вопрос?)

    • Имеется ввиду массив из координат точек, по которому нужно построить траекторию?

      • Я совсем недавно начал осваивать autolisp) сделал программу по образу и подобию вашей, только для других целей) Связанна с вертикальной планировкой в строительстве автомобильных дорог)

        программа вычерчивает полилинию нужной мне формы и размеров заданных в диалоговом окне, по аналогии с вашей командой mp_paral, как в примере видеоурока) И теперь стоит задача, чтобы помимо ввода параметров в диалоговом окне и вычерчиванию полилинии с нужной конфигурацей, программа сама вызывала команду "массивпотраект" ( т.е массив по траектории) и просила выбрать направляющую для массива вычерченной полилинии)

        Спасибо, что ответили) вы очень помогли мне) расширили мои возможности применения autocad'а, и дали почувствовать себя крутым чуваком :D Огромное спасибо вам)

        • Попробуйте так:

          (prompt "\nВыберите объекты для создания массива: ")
          (setq set_obj (ssget))
          (setq a_path (car (entsel "\nВыберите криволинейную траекторию: ")))
          (if (and set_obj a_path)
            (command "_arraypath" set_obj "" a_path "" "" "" "_F" "10" "" "")
            (princ "\nМассив не создан!")
          )
          • Спасибо большое) вы мне очень помогли)

            где можно найти информацию о том, за что отвечает та или иная переменная в данной приведенной вами строке?

            (command "_arraypath" set_obj "" a_path "" "" "" "_F" "10" "" "")

            Меня очень увлекло программирование в среде автокада, но я натыкаюсь на стену непонимания сложной профессиональной литературы) Не могли бы вы посоветовать хороший, по вашему мнению, учебник по AutoLisp?)

            с уважением, Арсений

          • set_obj - объекты из которых создается массив

            "" - подтверждаем выбор объектов (равносильно нажатию "Enter")

            a_path - криволинейная траектория.
            далее появляется:
            Введите количество элементов вдоль траектории или [Ориентация/Выражение] Ориентация:

            "" - подтверждаем значение по умолчанию

            Базовая точка или [КЛючевая точка] конец криволинейной траектории:

            "" - подтверждаем значение по умолчанию

            Задайте направление касательной или [2Точки/Нормаль] текущее:

            "" - подтверждаем значение по умолчанию

            Введите количество элементов или [Заполнить всю траекторию/Выражение] <1>:

            "_F" - Выбираем заполнить всю траекторию (в русско-язычной версии вместо "_F" можно ставить "З")

            Укажите расстояние между элементами вдоль траектории или [Поделить/ВСего/ВЫражение]:

            "10" - расстояние между элементами

            Элементы (9) невозможно поместить на траектории с использованием текущего интервала.
            Скорректировать интервал для размещения элементов на траектории? [Да/Нет] Да:

            "" - подтверждаем значение по умолчанию

            Выберите ручку, чтобы редактировать массив, или [Ассоциативный/Метод/Базовая точка/Направление касательной/Объекты/сТроки/Уровни/Выравнивание элементов/направление Z/вЫход] вЫход:

            "" - подтверждаем значение по умолчанию

            К сожалению, простых учебников по autolisp я не знаю.

  • Спасибо. А можете выложить видео работы с диалоговым окном с popup'ом (выпадающий список)

      • Здравствуйте, а можно попросить вас показать пример, использования многомерных массивов?

        • Как я понял массивов в Visual Lisp нет, сделал списком.

          • Столкнулся проблемой. Написал диалоговое окно, все хорошо. Но на следующий день Автокад не может его найти, даже если загружаю из окна AutoLisp

          • Пропишите ваш полный путь к диалоговому окну:

            (load_dialog "с:/Folder/MyDial.dcl")
  • Добрый день. Возможно ли загружать данные в диалоговое окно из Excel файла?

    • Да. AutoLisp может читать данные из Excel, и соответственно может загружать их в диалоговое окно DCL.

  • Доброй ночи. Возникла проблема
    Написано диалоговое окно, все отлично. Не загружается из окна AutoLisp,при проверке существования выдает ошибку, путь прописан полностью.

    • Присылайте мне на почту: acadprog@gmail.com ваш DСL-файл и LISP-файл. Я посмотрю в чем проблема.

  • Я просто скачал два файла, dcl и lsp, загрузил их во VLIDE, запустил, но мне не показывает диалогового окна, а при вызове mp_paral Command: mp_paral
    ; error: quit / exit abort происходит.Что делать??

    • Папка в которой лежит файл mp_paral.dcl должна быть указана, как папка для Вспомогательных файлов.
      Или пропишите ваш полный путь к диалоговому окну:

      (load_dialog "с:/Folder/mp_paral.dcl")
Share
Published by
Михаил Орлов

Recent Posts

Программа расчета профиля

Программа "Расчет профиля" создана в помощь инженерам-проектировщикам, работающих с профилями. Автор программы, читатель моего сайта:…

10 лет ago

Как нарисовать прямоугольник в Автокаде.

Любой чертеж может быть разбит на простейшие элементы, примитивы.  В этом уроке мы познакомимся с…

11 лет ago

Как нарисовать дугу в Автокаде.

Как нарисовать дугу в Автокаде? Для этого в программе Автокад существует несколько способов. В этом…

11 лет ago

Как нарисовать круг в Автокаде.

Любой чертеж может быть разбит на простейшие элементы, примитивы.  В этом уроке мы познакомимся с…

11 лет ago

Автоматизация проектирования. Отвод.

В этой статье мы продолжим процесс автоматизации проектирования систем вентиляции. (далее…)

11 лет ago

Автоматизация проектирования.

Одним из эффективных способов автоматизации процесса проектирования в Автокад,  может послужить создание своих программ на…

11 лет ago