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

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

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

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

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

См. Рис. 1.

Пример программы LISP

Рис. 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.

Пример программы LISP

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

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

Пример программы LISP

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

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

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

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

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

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

См. Рис. 4

Пример программы LISP

Рис. 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.

Пример программы LISP

Рис. 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.

Пример программы LISP

Рис. 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.

Пример программы LISP

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

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

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

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

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

Пример программы LISP

Рис. 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.

Пример программы LISP

Рис. 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 Скачать диалоговое окно Mp_paral.dcl (Размер файла: 392 bytes)

 Скачать программу Mp_paral.lsp Скачать программу 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.

Пример программы LISP

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

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

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

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

Пример программы LISP

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

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

Пример программы LISP

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

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

Пример программы LISP

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

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

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

Пример программы LISP

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

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

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

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

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

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

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

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

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

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

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

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

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

Google

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

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

  1. Веселов 30.06.2014 04:56

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

  2. Алексей 26.05.2015 09:45

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

    • Михаил Орлов 26.05.2015 20:52

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

  3. Алексей 20.08.2015 20:13

    Огромное спасибо

  4. Арсений 25.12.2015 20:48

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

  5. Арсений 26.12.2015 10:05

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

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

    • Михаил Орлов 26.12.2015 15:54

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

      • Арсений 29.12.2015 14:50

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

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

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

        • Михаил Орлов 12.01.2016 13:41

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

          (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Массив не создан!")
          )
          • Арсений 13.03.2016 19:22

            Спасибо большое) вы мне очень помогли)

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

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

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

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

          • Михаил Орлов 14.03.2016 13:51
            set_obj - объекты из которых создается массив

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  6. Рустам 19.02.2016 07:17

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

      • Рустам 24.03.2016 11:54

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

        • Noname 14.04.2016 12:20

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

          • Нниколай 15.05.2016 08:39

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

          • Михаил Орлов 15.05.2016 16:11

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

            (load_dialog "с:/Folder/MyDial.dcl")
  7. Нниколай 15.05.2016 08:33

    Добрый день. Возможно ли загружать данные в диалоговое окно из Excel файла?

    • Михаил Орлов 15.05.2016 16:04

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

  8. Тори 02.06.2017 20:38

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

    • Михаил Орлов 03.06.2017 12:25

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

  9. Павел 28.06.2017 12:18

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

    • Михаил Орлов 28.06.2017 18:43

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

      (load_dialog "с:/Folder/mp_paral.dcl")

Оставить комментарий

Ваш mail не будет опубликован.

Вы можете использовать HTML теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>