Преобразование объекта VT_DISPATCH

Автор Chipchilinka_1, 30.01.24, 11:25:27

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Chipchilinka_1

Я выделяю в компасе объект вручную .С помощью хэндлера получаю выделенный объект в виде vt_dispatch (<PyIDispatch at 0x0000015C781E6440 with obj at 0x0000015C7A47E9B8>).
Как можно преобразовать объект чтобы можно было использовать его в SetAssociationObject() .
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
part7 = kompas_document_3d.TopPart
auxiliary_geom_container = kompas_api7_module.IAuxiliaryGeomContainer(part7)
local_coordinate_systems = auxiliary_geom_container.LocalCoordinateSystems
local_coordinate_system = kompas_api7_module.ILocalCoordinateSystem(local_coordinate_systems.Add())
local_coordinate_system.Name = "ЛСК:1"
local_coordinate_system.OrientationType = kompas6_constants_3d.ksAxisOrientation
local_coordinate_system.ShowName = False
model_container = kompas_api7_module.IModelContainer(part7)
local_coordinate_system.SetAssociationObject('Хотелось бы тут в качестве аргумента использовать выделенную точку')
local_coordinate_system.Update()

Nipal

Зачем дублировать вопрос?
Если продублировали, то почему не в ветке по Питону?

Chipchilinka_1

#2
Цитата: Nipal от 30.01.24, 11:43:36Зачем дублировать вопрос?
Если продублировали, то почему не в ветке по Питону?
Ну так чтобы если ответят люди потом смогли найти и решить свою проблему ,да  и дело не пайтоне ,мне бы хоть как нибудь уже ответ получить. Боюсь если я скину в ветку по питону так ответа и не дождусь.
P.S. Я уже весь sdk перелопатил ничего найти вразумительного не могу
Вот вы же знаете наверное ответ, но почему то не хотите помочь(

Вират Лакх

Кто такой "хэндлер"?
Приведите сюда кусок полностью, который можно запустить. Всю программу не надо, а выжимку.
Не показали, как вы этот vt_dispatch получили.
Преобразование типа делается как вы используете kompas_api7_module.IKompasDocument3D(kompas_document)
Например, получение интерфейса запущенного компаса (обёртка полученного объекта):
from win32com.client import gencache
from pythoncom import connect

api5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)

print(connect('Kompas.Application.5'))
# <PyIDispatch at 0x000001E38391F160 with obj at 0x000001E3839146B8>
print(api5.KompasObject(connect('Kompas.Application.5')))
# <win32com.gen_py.0422828C-F174-495E-AC5D-D31014DBBE87x0x1x0.KompasObject instance at 0x2076642970704>
Выделенные объекты питон при наличии библиотеки типов методами api компас должен выдать соответствующих типов. Почему у вас PyIDispatch?

Chipchilinka_1

#4
Цитата: Вират Лакх от 30.01.24, 12:35:16Кто такой "хэндлер"?
Приведите сюда кусок полностью, который можно запустить. Всю программу не надо, а выжимку.
Не показали, как вы этот vt_dispatch получили.
Преобразование типа делается как вы используете kompas_api7_module.IKompasDocument3D(kompas_document)
Например, получение интерфейса запущенного компаса (обёртка полученного объекта):
from win32com.client import gencache
from pythoncom import connect

api5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)

print(connect('Kompas.Application.5'))
# <PyIDispatch at 0x000001E38391F160 with obj at 0x000001E3839146B8>
print(api5.KompasObject(connect('Kompas.Application.5')))
# <win32com.gen_py.0422828C-F174-495E-AC5D-D31014DBBE87x0x1x0.KompasObject instance at 0x2076642970704>
Выделенные объекты питон при наличии библиотеки типов методами api компас должен выдать соответствующих типов. Почему у вас PyIDispatch?
Получил с помощью обработчика событий app_notify_event = BaseEvent(kompas_api7_module.ksSelectionMngNotify, on_app_notify_event, selectionMng)
в функции получаю от ksSelectionMngNotify.
Код неудобно будет так как он по нескольким модулям раскидан.
Хэндлер это обработчик событий
А как идет преобразование типа если по сути переменную я никуда не передавал
Да  и  у меня вопрос как объект выделения в виде pydispatch преобразовать чтобы я мог его подставить в SetAssociationObject

Starik

Уважаемый Chipchilinka_1 это что за мания создавать подряд несколько сообщений с одной и той же цитатой?
Объявляю Вам ЗАМЕЧАНИЕ.
Думаете мне больше делать нечего кроме как объединять ваши разрозненные сообщения в одно?
И пока ещё не придумал, но подумаю, может стоит объединить ваши две однотипные темы в одну, как Вам уже говорили выше :um:

Михаил88

Пример

def on_app_notify_event(command_id, params):
    try:
        rez, x, y, z = Dispatch(params[0]).GetPoint()
        print(rez, x, y, z)
    except Exception:
        pass

Для примера выделяете точку и получаете ее координаты
Screenshot_1.png

Screenshot_2.png
+ Благодарностей: 3

Вират Лакх

Второе и третье сообщение тоже следует объединить.
Переместить в ветку питона точно надо.
Если рассматривать вопрос в соответствии с заголовком, то можно оставить как отдельную тему.
А вот куда и как пихать преобразованный объект - это другая тема.
В приведенном примере мы знаем, в какой класс обернуть объект. Если заранее не знаем, то думаю, что должно прокатить преобразование к базовому классу IKompasAPIObject, у которого можно узнать тип объекта. Зная его, будем знать, к какому интерфейсу привести объект.

Вират Лакх

Цитата: Михаил88 от 30.01.24, 14:07:17Dispatch(params[0])
Отличный ответ в одно слово! :cl:
Давайте в научных целях его разберём? 88)) В Dispatch много чего написано. Интересно оттуда взять нужное.
+ Благодарностей: 1

Chipchilinka_1

#9
Цитата: Михаил88 от 30.01.24, 14:07:17Пример

def on_app_notify_event(command_id, params):
    try:
        rez, x, y, z = Dispatch(params[0]).GetPoint()
        print(rez, x, y, z)
    except Exception:
        pass

Благодарю, Михаил в очередной раз выручили

Для примера выделяете точку и получаете ее координаты
Screenshot_1.png

Screenshot_2.png

Кстати при таком коде почему то выдает ошибку. Может я конечно что то не понимаю но у вас же вроде работает)Есть подозрения что у вас на входе в атрибуте params в хэндлере уже pydisp api7 и на выходе после dispatch получается уже не ksentity
AttributeError: '<win32com.gen_py.0422828C-F174-495E-AC5D-D31014DBBE87x0x1x0.ksEntity instance at 0x1528546290832>' object has no attribute 'GetPoint'

Михаил88

Полный вариант. Запускаете потом в детали выбираете точку.
Дальше я думаю разберетесь.
+ Благодарностей: 1

Chipchilinka_1

Цитата: Chipchilinka_1 от 30.01.24, 17:39:23Кстати при таком коде почему то выдает ошибку. Может я конечно что то не понимаю но у вас же вроде работает)Есть подозрения что у вас на входе в атрибуте params в хэндлере уже pydisp api7 и на выходе после dispatch получается уже не ksentity
AttributeError: '<win32com.gen_py.0422828C-F174-495E-AC5D-D31014DBBE87x0x1x0.ksEntity instance at 0x1528546290832>' object has no attribute 'GetPoint'
Да ,как я и думал основой подписки может быть и selectionmanager api7 .
Кстати чтобы не использовать ткинтер пр  обработке событий (Чтоб это окошко не мешало) советую использовать класс pythoncom PumpWaitingMessages (Он также служит для получения событий, сообщений , но нужно дописать бесконечный цикл т.к обьект класса принимает всего одно за раз сообщение,событие)Также можно использовать асинхронную обработку событий в библиотеке asyncio и в редких случаях pygame (там также есть обработчик событий)
+ Благодарностей: 1

Михаил88

Цитата: Chipchilinka_1 от 30.01.24, 18:00:08PumpWaitingMessages (Он также служит для получения событий, сообщений , но нужно дописать бесконечный цикл т.к обьект класса принимает всего одно за раз сообщение,событие)

Спасибо за информацию, попробую как-нибудь.

Михаил88

#13
Цитата: Вират Лакх от 30.01.24, 14:44:43Отличный ответ в одно слово! :cl:
Давайте в научных целях его разберём? 88)) В Dispatch много чего написано. Интересно оттуда взять нужное.
Я если честно глубоко не разбирался. У меня несколько лет назад была подобная задача и в одной из статей в интернете нашел такое решение.

Вират Лакх

Итого на примере интерфейса приложения через тип или класс объекта (как замена Dispatch):
from pythoncom import connect
from win32com.client import gencache

PyIDispatch = connect('Kompas.Application.7')

tla = PyIDispatch.GetTypeInfo().GetContainingTypeLib()[0].GetLibAttr()
api7 = gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4])

if api7.IKompasAPIObject(PyIDispatch).Type == 10001: # ksObjectApplication
    print(api7.IApplication(PyIDispatch))

klass = gencache.GetClassForCLSID(PyIDispatch.GetTypeInfo().GetTypeAttr()[0])
print(klass(PyIDispatch))
+ Благодарностей: 3