Название: QAction добавить сигналы ДО triggeted Отправлено: Nimbus от Октябрь 08, 2014, 13:15 Доброго времени суток.
В приложении на С++ где-то внутри сохранён указатель на экземпляр QAction и добавлен на какие-то меню/тулбары. На сигнал triggered() этого экземпляра законнекчено неизвестное количество каких-то QObject-ов (пусть набор этих соединений со слотами будет называться "хэндлером по-умолчанию"). Теперь, получив извне доступ к этому экземпляру QAction (в данном случае запускается питоновый интерпретатор, в котором запускается какой-то кастомный питоновый код, в контексте этого самого процесса с QAction'ом, имеющий у себя в арсенале биндинги PySide, но это сейчас не важно), очень нужно обернуть хэндлер по-умолчанию своим кодом. То есть, чтобы сигнал triggered() вызвал сначала какой-то наш кастомный слот ДО вызова хэндлера по-умолчанию, затем сам хэндлер по-умолчанию, и затем ещё какой-то наш кастомный слот. Типичный сценарий такой -- имеется QMenu в С++ приложении. Добавить вызов какого-то кода ДО клика на определённом пункте меню и ПОСЛЕ. С вызовом слота после проблем нет -- добавить новый коннект. А вот ДО... Можно попытаться добавить Proxy-объект, хранящий оригинальный QAction, который заменял бы его когда нужно на свой кастомный QAction, в слоте на on_triggered вызывался бы код ДО, затем оригинальный QAction.trigger() и код ПОСЛЕ. Однако, такой механизм имеет ряд недостатков, один из которых -- приложение по прежнему оперирует оригинальным экземпляром QAction'а и не знает ничего, что его подменили в меню, соответственно попытки сделать недоступным для клика (или изменить shortcut) приведут лишь к изменению оригинального, а proxy-объект не узнает об этом. Переконнектить его тоже не получится -- мы не знает ничего про хэндлер по-умолчанию в этом контексте. Знаем только, что он есть. Другой вариант -- изменить само С++ приложение, чтобы QAction имел в своём составе Proxy-объект, к которому он бы коннектился и к которому уже коннектился бы хэндлер-по умолчанию и имелась бы возможность получить этот объект извне, например через вызов QMetaObject::invokeMethod. К сожалению это серьёзное архитектурное изменение, требующее значительных затрат и изменений кода и тестов. Хорошо бы иметь какую-то очередь коннектов, в которую уже можно будет вставлять элементы с начала или конца. Но это лишь пожелание. И да, я лишь описал единичный случай. Хотелось бы такое проделывать для любых QAction'ов, которые мы возьмём из приложения. Кто-нибудь знает другие способы? Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Bepec от Октябрь 08, 2014, 13:25 На мой взгляд очень ненужная и опасная штука у вас выходит. А если там цикл бесконечный или ошибка?
К тому же не видно смысла. Зачем вам это? Вкратце - вам нужно чтобы вызывался слот triggered после обработки питоновского скрипта. Как делать - создать своего потомка от QAction в котором перед посылкой сигнала вызывать питоновский скрипт. Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Nimbus от Октябрь 08, 2014, 13:32 На мой взгляд очень ненужная и опасная штука у вас выходит. А если там цикл бесконечный или ошибка? К тому же не видно смысла. Зачем вам это? Вкратце - вам нужно чтобы вызывался слот triggered после обработки питоновского скрипта. Как делать - создать своего потомка от QAction в котором перед посылкой сигнала вызывать питоновский скрипт. Это уже пользователям решать, они будут писать скрипт. К тому же, С++ приложение НЕ знает ничего что внутри питонового скрипта. Оно просто поднимает интерпретатор и запускает скрипт. Скрипт вызывает единожды, а уже в нём навешиваются какие-то хэндлеры и кастомизируется приложение. Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Nimbus от Октябрь 08, 2014, 13:40 Я имею в виду, что у пользователей ДОЛЖНА быть возможно завернуть обработку сигнала triggered в свой код, имея в контексте возможность вызвать хэндлер по-умолчанию.
Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Bepec от Октябрь 08, 2014, 17:49 Ну блин поставьте там запуск файла myscript.py.
Если файла нет, то стандартный вызов сигнала. Вот и вся логика. Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Nimbus от Октябрь 08, 2014, 18:08 Ну блин поставьте там запуск файла myscript.py. Если файла нет, то стандартный вызов сигнала. Вот и вся логика. Видимо я неясно выразился. Это было бы нарушением абстракции. У нас нет цели сделать запуск скрипта по какому-то событию. У нас есть цель обеспечить возможность пользователям-программистам вклинить(/заменить наши на) свои хэндлеры на наши QAction'ы. Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Bepec от Октябрь 08, 2014, 23:13 Так и не понял вашей логики. Можете привести цепочку вызовов без словесной шелухи?
Нажатие экшена - вызов *** - вызов Qt слотов? Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Igors от Октябрь 09, 2014, 07:42 А не дописать ли нужный код в moc файл? (ну конечно запретив его пере-генерацию)
Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Old от Октябрь 09, 2014, 08:37 2JC Если есть возможность заменить в c++ программе все QAction на, какие нибудь, MyAction, то я придумал неплохое решение.
Да, MyAction это прямой наследник QAction, т.е. в программе ничего кроме названия класса переделывать не придётся. P.S. Пишу с телефона, поэтому сразу решение расписывать лениво. :) Название: Re: QAction добавить сигналы ДО triggeted Отправлено: Igors от Октябрь 09, 2014, 08:51 Есть такой ходик (qt_signal_spy_callback_set)
Код Блокировать не видно как, но "до" и "после" есть |