Название: Организация скриптов в приложении Отправлено: Igors от Октябрь 24, 2013, 11:11 Добрый день
Есть 2 вида скриптов. Первый применяется при действии пользователя внутри приложения, напр (псевдокод) Цитировать Object2.position = vec3(Object1.position.x, Object1.position.y, Object1.position.z + 100); Теперь если пользователь интерактивно двигает Object1, то Object2 движется вместе с ним.Скрипт второго типа как бы просто команда, вызывается пользователем напр из меню и отрабатывет 1 раз, псевдокод Цитировать Object1 = CreateObject("Sphere"); Пользователь должен иметь возможность создавать, редактировать и удалять скрипты из приложения.Object1.radius = 10; Object1.move(100, 100, 100); Как бы Вы задумали такое UI (в принципе, функционал)? Какие должны быть бубочки, где и что они должны делать? Спасибо Название: Re: Организация скриптов в приложении Отправлено: sergek от Октябрь 24, 2013, 20:52 Для себя я выбрал такой вариант (см. картинку). Скрипты (Python) хранятся в БД, выбираем в списке (Хранилище сценариев), отображается в окне редактора. Можно создать, редактировать скрипт. В списке скрипты организованы в виде древовидного списка аналогично файловой системе.
Текущий скрипт можно исполнить. Результат - созданный объект (список объектов), который добавляется и отображается в таблице (вкладки ЭПД, ЭСИД), доступен для различных действий (просмотр, печать, редактирование, сохранение в файл и т.д.). Ваш первый тип скриптов отличается от этого варианта тем, что скрипт можно в процессе исполнения программы динамически извлекать из БД по его id и исполнять (например, когда тащите объект). Легко реализуемо. Поддержка скриптов - на PythonQt, взаимодействие программы и скриптов - через шлюз, основанный на врапперах классов объектов, используемых и в программе и в скриптах. В документации по PythonQt этого нет, но все просто, достаточно посмотреть пару примеров. Шлюз обеспечивает функциональность, необходимую для работы с объектами. Если нужно, могу предоставить ссылку на полный проект в исходниках, где есть и готовый виндовый исполняемый файл. Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 25, 2013, 18:27 Проект не нужен, но все равно спасибо. Да, у Вас все норм (может тулбар здоровый как лапоть, ну то дело вкуса). Мне держать в базе - не очень с руки. Приложение помещает свои плагины в определенные фолдера - ну и файлы скриптов по аналогиии, почему нет? "Локальные" скрипты проще сохранить в файле проекта. Дерево тоже как-то не лепится к моему случаю, т.к. в обозримом будущем не видно ни одного хоть какого-то "ветвления".
Понимаю что в Вашем случае это "то что надо", просто оно механически не переносится :) Спасибо Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 28, 2013, 13:43 Поддержка скриптов - на PythonQt, взаимодействие программы и скриптов - через шлюз, основанный на врапперах классов объектов, используемых и в программе и в скриптах. В документации по PythonQt этого нет, но все просто, достаточно посмотреть пару примеров. Подключил PythonQt и уже прорвался к "hello world" (т.е. могу выполнять простые скрипты из приложения).Вопрос начинающего (пытона раньше никогда не видел). Вот есть такой скрипт Цитировать Object1.position.x = 0 # Object1 - объект основного приложния Понятно что я могу сделать wrap для Object1, но как это сделать "на лету"? То есть экземпляров (таких как Object1) у меня могут быть тысячи, а в скрипте используется всего 1 - ну не должен же я врапить все тысячи перед каждым выполнением скрипта? Спасибо Edit: Или я должен действовать примерно так Цитировать prj.GetObject("Object 1").position.x = 0 А объект prj отврапить (текущий проект приложения всегда 1)Название: Re: Организация скриптов в приложении Отправлено: sergek от Октябрь 29, 2013, 09:30 Цитировать Object1.position.x = 0 # Object1 - объект основного приложния Понятно что я могу сделать wrap для Object1, но как это сделать "на лету"? То есть экземпляров (таких как Object1) у меня могут быть тысячи, а в скрипте используется всего 1 - ну не должен же я врапить все тысячи перед каждым выполнением скрипта? 2) Как правило, требуется возможность передачи данных из программы в Питон (имеется в виду встроенный в программу интерпретатор) и обратно. Такая возможность существует. Как лучше ее организовать, зависит от задачи. Я не все возможности PythonQt знаю, только те, которые мне потребовались для реализации моего проекта. Поэтому лучше вам сформулировать, что нужно, а я попробую помочь. 3) Посмотрите доку http://pythonqt.sourceforge.net/index.html (http://pythonqt.sourceforge.net/index.html), в частности, раздел "Developer", примеры. Но документация не включает некоторые возможности, например, в ней не описан способ эмуляции свойств (obj.property = v). Можно почитать конференцию Флориана: http://sourceforge.net/p/pythonqt/discussion/631392 (http://sourceforge.net/p/pythonqt/discussion/631392). Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 10:08 Но документация не включает некоторые возможности, например, в ней не описан способ эмуляции свойств (obj.property = v). Можно почитать конференцию Флориана: http://sourceforge.net/p/pythonqt/discussion/631392 (http://sourceforge.net/p/pythonqt/discussion/631392). Именно на этом я сейчас застрял :) Если нетрудно, укажите топик конференции (пока не нашел). СпасибоОбертка (wrapper) делается не для объекта, а для класса. То ясно, просто сейчас в приложении есть какой-то самопальный скриптинг который позволяет обращаться "Object1" при условии что Object1 есть в приложении. В пытоне так нельзя, переменная должна быть объявлена присваиванием (если не так - поправьте)Большинство объектов у меня статично, их данные известны и неизменны. Но не все - есть плагины которые создают свои данные динамически. Напр в UI плагина пользователь выбрал "сфера" - появился параметр "радиус". Потом поменял на "куб" - уже др. параметры. Я могу это оформить методами (код скрипта) Цитировать obj.setParam("radius", 10); Но пользователю это не очень удобно, он хочет такЦитировать obj.radius = 10; Как бы это порешать? Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 10:28 Именно на этом я сейчас застрял :) Если нетрудно, укажите топик конференции (пока не нашел). Спасибо http://sourceforge.net/p/pythonqt/discussion/631392/thread/278533e7/В пытоне так нельзя, переменная должна быть объявлена присваиванием (если не так - поправьте) Нужно регистрировать все необходимые объекты в контексте питона, тогда к ним можно будет обращаться из скрипта.Есть 100500 плюсовых объектов, все нужно зарегистрировать. Название: Re: Организация скриптов в приложении Отправлено: sergek от Октябрь 29, 2013, 10:34 Но документация не включает некоторые возможности, например, в ней не описан способ эмуляции свойств (obj.property = v). Можно почитать конференцию Флориана: http://sourceforge.net/p/pythonqt/discussion/631392 (http://sourceforge.net/p/pythonqt/discussion/631392). Именно на этом я сейчас застрял :) Если нетрудно, укажите топик конференции (пока не нашел). СпасибоНо пользователю это не очень удобно, он хочет так Цитировать obj.radius = 10; Как бы это порешать? Простейший пример: Исходный класс: Код: class CPartInfo Код: class CPartInfoWrapper : public QObject { Код: // инициализация библиотеки PythonQt Код: CDepartmentalInfo* py_get_DepartmentalInfo(CED101* o) { return &o->DepartmentalInfo; } Код: >part=CPartInfo() Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 11:19 http://sourceforge.net/p/pythonqt/discussion/631392/thread/278533e7/ http://sourceforge.net/p/pythonqt/discussion/631392/thread/278533e7/ (http://sourceforge.net/p/pythonqt/discussion/631392/thread/278533e7/) Работает, спасибо! Оказывается есть "волшебные слова" py_get_ и py_set_ :)Есть 100500 плюсовых объектов, все нужно зарегистрировать. Надо - так надо, но как мне сделать это динамически, на этапе выполнения? Пусть юзверь написал в скриптеЦитировать obj = prj.GetObject("Object1") Вероятно, сейчас будет обращение к атрибутам Object1, и мне известны все их имена и типы данных. Но я не могу их знать до выполнения. Напр в любой момент юзверь может подключить файл плагина который мне был неизвестен но который объявит свои пропердии. Как бы вот тут разрулить?Спасибо Название: Re: Организация скриптов в приложении Отправлено: sergek от Октябрь 29, 2013, 11:36 Надо - так надо, но как мне сделать это динамически, на этапе выполнения? Пусть юзверь написал в скрипте Легко. Можно регистрировать не только классы, но и объекты. В этом случае в скриптах эти объекты сразу доступны для использования, а в программе - результат их использования. Примерно так:Цитировать obj = prj.GetObject("Object1") Вероятно, сейчас будет обращение к атрибутам Object1, и мне известны все их имена и типы данных. Но я не могу их знать до выполнения. Напр в любой момент юзверь может подключить файл плагина который мне был неизвестен но который объявит свои пропердии. Как бы вот тут разрулить?Код: // объект Код: >gate.prop1 = val; Только для случая регистрации объектов необходимо, чтобы класс этого объекта (CScriptGateway) должен быть порожден от QObject. Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 13:04 Легко. Можно регистрировать ... Да, работает! И для "цепочек" тожеКод После этого я могу писать в скрипте Код: print prj.ptop1.prop2 Спасибо Название: Re: Организация скриптов в приложении Отправлено: sergek от Октябрь 29, 2013, 13:12 А могу ли я удалить cls (или использовать локальный) - или этот экземпляр должен существовать? Пока используете его в скрипте, должен, разумеется. Поэтому объект должен быть в пределах видимости модуля, гда используется Питоновский скрипт.А вот потом - хз. Если есть addObject, то, скорее всего, должен быть что-нибудь вроде removeObject... Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 16:09 А могу ли я удалить cls (или использовать локальный) - или этот экземпляр должен существовать? Конечно, для работы с ним из скрипта он должен существовать. Но можно указать питону, что бы он сам уничтожил этот объект, когда последняя ссылка на него исчезнет. Или наоборот, не уничтожил объект, который в скрипте уже не используется, но необходим в хост-программе.Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 17:10 Также я могу комбинировать поля и методы, напр
Код: print prj.prop1.prop2 Спасибо Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 17:31 Однако хотелось бы создавать prop2 динамически, в тот момент когда произошло (скриптовое) обращение к prop1 (возможно кешируя). Ну так у вас вызовется метод объекта вашего врапера, при обращении к prop1. В нем и создавайте динамически объект.Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 17:59 Ну так у вас вызовется метод объекта вашего врапера, при обращении к prop1. В нем и создавайте динамически объект. Это если пропердия заряжена с помощью py_get_ и py_set_. Но это не очень выгодно, поэтому я просто наследуюсь от QObject и делаю setProperty. Все норм, пытон ее видит, кстати можно и из самого пытонаКод: prj.setProperty("myProp", 1) Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 18:14 Вы используете объект QObject только для хранения свойств? :)
Вы можете описать свой класс-наследник QObject и задать все необходимые propery с геттерами/сеттерами, которые и будут использоваться из питона. См.: http://doc.crossplatform.ru/qt/4.6.x/properties.html Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 19:34 Вы используете объект QObject только для хранения свойств? :) Могу, но не хочу т.к. мне придется делать "пытон-копии" для многочисленных и обширных классов. Мне же хочется "опубликовать" в пытоне только проперди объектов которые известны в общем видеВы можете описать свой класс-наследник QObject и задать все необходимые propery с геттерами/сеттерами, которые и будут использоваться из питона. См.: http://doc.crossplatform.ru/qt/4.6.x/properties.html Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 19:44 Мне же хочется "опубликовать" в пытоне только проперди объектов которые известны в общем виде И в чем противоречие, пожалуйста хотите общие, хотите частные. :)Я вам предлагаю описать функции геттер с помощью Qt системы свойст, которая и будет создавать нужный объект "на лету". От вас кроме этого ничего не понадобиться, просто добавить строку Q_PROPERTY. Никаких многочисленных классов описывать не придется. Из питона это будет как чтение свойства, а в плюсовом контексте будет вызываться метод. Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 20:17 Внутри приложения примерно так
Код Поэтому городить сотни геттеров/сеттеров нет смысла Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 20:22 Вопрос один: как это все соотносится с вопросом о динамическом создании объекта при чтении свойства?
:) Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 29, 2013, 20:39 Вопрос один: как это все соотносится с вопросом о динамическом создании объекта при чтении свойства? Пользователь может написать напр такой скрипт:) Код: obj.Color.red = 255 Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 29, 2013, 20:55 Пользователь может написать напр такой скрипт Что значит глупо? Это обязательное условие. Все действия для вашего объекта должны быть полностью за декларированы в контексте скрипта. Абсолютно все.Код: obj.Color.red = 255 То что за вас большую часть работы делает Qt + PythonQt, вовсе не означает что эта работа не делается. Будет пользователь сейчас что-то вызывать или он это сделает завтра не важно, все должно быть описано перед использованием в скрипте. Поэтому, если пользователь сейчас (или через 10 лет) захочет написать obj.Color.red = 255, то сеттер для такого присвоения должен быть. Его вы можете написать сами, а можете оставить на совести Qt с PythonQt. Теперь по поводу примера: Код
Если объект Channel наследник QObject, то нам достаточно добавить описание необходимых свойст и они автоматом станут доступны из питона: Код Больше никаких телодвижений не понадобиться, все остальное сделает Qt с PythonQt. А если Channel не наследник, то вам все равно придется все расписывать руками, каждый сеттер и каждый геттер, не зависимо от того, будет это PythonQt или boost::python. Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 30, 2013, 11:15 Будет пользователь сейчас что-то вызывать или он это сделает завтра не важно, все должно быть описано перед использованием в скрипте. Поэтому, если пользователь сейчас (или через 10 лет) захочет написать obj.Color.red = 255, то сеттер для такого присвоения должен быть. Нет, можно делать геттеры/сеттеры динамически, только когда они юзаются в пытоне. Вот фрагмент работающего примераКод
Если объект Channel наследник QObject, то нам достаточно добавить описание необходимых свойст и они автоматом станут доступны из питона: Конечно будут, но такой "механический" перенос ничего не дает, пользователю нужно не "внутреннее устройство", а упрощенный синтаксис. Перелопатить все классы чтобы его добавить - глупо, нужно использовать механизм dynamic properties, для него все естьНазвание: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 30, 2013, 11:23 Нет, можно делать геттеры/сеттеры динамически, только когда они юзаются в пытоне. Вот фрагмент работающего примера Где вы здесь видите динамические геттеры/сеттеры? Здесь вы создаете новое свойство, а геттеры/сеттеры для него сделает Qt, точнее ее система свойств. О чем я и писал выше.Пример, по крайней мере, странный. Что это дает не понятно. Объект уже существует, у него или есть какие-то свойства или их нет. Почему они должный появляться или исчезать не понятно. Вот есть точка, у нее есть два свойства - координаты x и y. Они есть всегда. Название: Re: Организация скриптов в приложении Отправлено: Igors от Октябрь 30, 2013, 11:41 Пример, по крайней мере, странный. Что это дает не понятно. Объект уже существует, у него или есть какие-то свойства или их нет. Почему они должный появляться или исчезать не понятно. Вот есть точка, у нее есть два свойства - координаты x и y. Они есть всегда. Не всегдаБольшинство объектов у меня статично, их данные известны и неизменны. Но не все - есть плагины которые создают свои данные динамически. Напр в UI плагина пользователь выбрал "сфера" - появился параметр "радиус". Потом поменял на "куб" - уже др. параметры. Да и не в этом даже дело. Просто расписать "все что (может быть) нужно пытону" - уже работа на неделю. Отловить все места где вместо одних параметров могут быть другие - еще неделя.Хорошо, а как насчет пресловутой "архитектуры"? Как это должно выглядеть с точки зрения приложения. где хранить данные доступные из скриптов? 1) Прямо в самих классах и пытон их меняет. Не верится, как-то стремно 2) Приклеить к классам что-то типа CPyObject * 3) Мапа <объект *, CPyObject *> 4) Еще ходы? Спасибо Название: Re: Организация скриптов в приложении Отправлено: Old от Октябрь 30, 2013, 12:37 Не всегда Всегда.Хорошо, а как насчет пресловутой "архитектуры"? Как это должно выглядеть с точки зрения приложения. где хранить данные доступные из скриптов? Не знаю с какого боку тут архитектура, но все это дело со скриптами как раз делается для того, что бы пользователь с минимальными усилиями мог работать с внутренними структурами программы, поэтому первый вариант самый оптимальный по соотношению кодирование/результат. Если пользователю сложно напрямую работать с объектами Host-программы, то можно сделать промежуточный слой, но тут придется весь этот простой слой кодировать (будь то новые классы или упрощенные функции). |