Russian Qt Forum
Сентябрь 22, 2024, 19:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: Сигналы и слоты в плагинах  (Прочитано 20936 раз)
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #15 : Август 20, 2012, 18:16 »

Пока писал, увидел, что andrew.k свой пост отредактировал Улыбающийся.
Если нужно получить общий QObject предок для всех SonyCamera и т.п., то можно (и нужно) добавить еще одну прослойку типа CommonCameraInterface в которой описать все нужные сигналы/слоты и прочий общий функционал. А наружу из плагина пусть торчит голый интерфейс.

Код
C++ (Qt)
class CameraInterface
{
};
 
class CommonCamera : public QObject, public CameraInterface
{
signals:
 initDone();
};
 
class SonyCamera : public CommonCamera
{
 void doInit()
 {
   ...
  emit initDone();
 }
};
 
« Последнее редактирование: Август 20, 2012, 18:17 от xokc » Записан
andrew.k
Гость
« Ответ #16 : Август 20, 2012, 18:16 »

Вот тебе пример как раз.
Я даю тебе интерфейс для плагина и говорю, напиши-ка мне плагин SuperDuperCamera.

Код
C++ (Qt)
#ifndef IPLUGIN_H
#define IPLUGIN_H
 
#include <QtCore>
 
class CameraInterface
{
public:
   virtual ~CameraInterface() {}
 
   virtual void powerOn() = 0;
   virtual void powerOff() = 0;
};
 
Q_DECLARE_INTERFACE(CameraInterface, "ru.prog.test.CameraInterface/1.0")
 
#endif // IPLUGIN_H
 
Ты пишешь, но ничего не работает, а оказывается в реализации нужно было еще сигналы испускать.
А какие нужны сигналы скрыто в реализации, к которой доступ по идее не нужен.
Таким образом ты предлагаешь подглядывая в имеющуюся реализацию делать копипастой.
« Последнее редактирование: Август 20, 2012, 18:18 от andrew.k » Записан
andrew.k
Гость
« Ответ #17 : Август 20, 2012, 18:17 »

Пока писал, увидел, что andrew.k свой пост отредактировал Улыбающийся.
Если нужно получить общий QObject предок для всех SonyCamera и т.п., то можно (и нужно) добавить еще одну прослойку типа CommonCameraInterface в которой описать все нужные сигналы/слоты и прочий общий функционал. А наружу из плагина пусть торчит голый интерфейс.
Так удали лишнее сообщение, чтобы не смущать никого)
Записан
andrew.k
Гость
« Ответ #18 : Август 20, 2012, 18:17 »

Пока писал, увидел, что andrew.k свой пост отредактировал Улыбающийся.
Если нужно получить общий QObject предок для всех SonyCamera и т.п., то можно (и нужно) добавить еще одну прослойку типа CommonCameraInterface в которой описать все нужные сигналы/слоты и прочий общий функционал. А наружу из плагина пусть торчит голый интерфейс.
Давай пример, как ты это видишь.
Записан
andrew.k
Гость
« Ответ #19 : Август 20, 2012, 18:24 »

Мы рассинхронизировались Улыбающийся. Мой пример в моем предыдущем посту.
Ну так я ж из твоего примера взял интерфейс.
Как написать реализацию, имея интерфейс, который я тебе предоставил? Не подсматривая в имеющуюся реализацию никак.

Да какой смысл в описании сигналов в интерфейсе-то?
Если отвечать на этот вопрос, то это будет в четвертый раз в этом топике, наверное.

Я уже другой пример прошу, не рабочий, просто в псевдокоде.
Вот для этой мысли пример:
Если нужно получить общий QObject предок для всех SonyCamera и т.п., то можно (и нужно) добавить еще одну прослойку типа CommonCameraInterface в которой описать все нужные сигналы/слоты и прочий общий функционал. А наружу из плагина пусть торчит голый интерфейс.
Как я понимаю, мы опять получим CommonCameraInterface испускающий сигналы. И в чем разница?
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #20 : Август 20, 2012, 18:41 »

Попытаюсь всё же засинхронизироваться. Удалил один пост, а то нить беседы теряется.
Вот тебе пример как раз.
Я даю тебе интерфейс для плагина и говорю, напиши-ка мне плагин SuperDuperCamera.
Ты пишешь, но ничего не работает, а оказывается в реализации нужно было еще сигналы испускать.
А какие нужны сигналы скрыто в реализации, к которой доступ по идее не нужен.
Таким образом ты предлагаешь подглядывая в имеющуюся реализацию делать копипастой.
Из того, что в CameraInterface будут присутствовать сигналы, никак не вытекает порядок их испускания, так что всё равно нужно будет иметь либо документацию, либо пример.
В моём варианте имея CommonCamera ты получишь то, чего тебе не хватало в CameraInterface, а кроме того можешь еще часть общей для всех камер логики в нем реализовать. Например, флаг m_power.

Как я понимаю, мы опять получим CommonCameraInterface испускающий сигналы. И в чем разница?
Разница в том, что из plugin dll в этом случае будет торчать наружу только голый интерфейс. Этот плагин (теоретически) можно даже будет использовать и в приложении без Qt, и даже без С++.
Кроме того, честно говоря я не уверен, что конструкция вида
Код
C++ (Qt)
class CameraInterface : public QObject
{
   Q_OBJECT
public:
   virtual ~CameraInterface() {}
   virtual void powerOn();
};
 
Q_DECLARE_INTERFACE(CameraInterface, "ru.myCompany.myApp.cameraInterface/1.0")
 
легитимна, поскольку:
1. Making an application extensible through plugins involves the following steps:
Define a set of interfaces (classes with only pure virtual functions) used to talk to the plugins.

Здесь мы делаем CameraInterface, который и экспортируется из плагина.
2. Writing a plugin involves these steps:
Declare a plugin class that inherits from QObject and from the interfaces that the plugin wants to provide.

Здесь мы имеем CommonCamera или SonyCamera, порождённую как от CameraInterface, так и от QObject.
То есть если вариант с class CameraInterface : public QObject сейчас и работает, то это происходит вопреки требованиям Qt developer и совсем не факт, что будет работать и далее.
« Последнее редактирование: Август 20, 2012, 18:49 от xokc » Записан
andrew.k
Гость
« Ответ #21 : Август 20, 2012, 19:00 »

В с++ интерфейс уже сам по себе довольно абстрактное понятие (это просто особого вида класс), для него нет специальной языковой конструкции.
Поэтому это работает и будет работать.
Поэтому я не вижу никакого смысла, разделять общий класс на два уровня.

Поэтому это:
Код
C++ (Qt)
class CameraInterface
{
};
 
class CommonCamera : public QObject, public CameraInterface
{
signals:
 initDone();
};
ничем не отличается от этого:
Код
C++ (Qt)
class CameraInterface : public QObject
{
signals:
 initDone();
};
Кроме дополнительного уровня иерархии, призванного избавить класс нареченный "интерфейсом" не иметь сигналов и не более.

И опять же, в твоем примере ты будешь пользоваться только CommonCamera, а CameraInterface автоматом станет не особенно нужен, потому что первый по сути будет выполнять функции второго.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #22 : Август 20, 2012, 20:05 »

Предлагаю на этом и остановиться, дабы не уподобляться "тому, чье имя нельзя называть вслух" и чья цитата у тебя в подписи. Кстати, странно, что он тут ещё не отписался. Если у топикстартера ко мне вопросы есть - отвечу, если нет - откланиваюсь.
Записан
andrew.k
Гость
« Ответ #23 : Август 20, 2012, 20:15 »

Предлагаю на этом и остановиться, дабы не уподобляться "тому, чье имя нельзя называть вслух" и чья цитата у тебя в подписи. Кстати, странно, что он тут ещё не отписался. Если у топикстартера ко мне вопросы есть - отвечу, если нет - откланиваюсь.
Согласен. В общем-то все понятно.
Спасибо за дискуссию.
Записан
lighting
Гость
« Ответ #24 : Август 20, 2012, 23:34 »

Если у топикстартера ко мне вопросы есть - отвечу, если нет - откланиваюсь.
Да вопрос есть - мне непонятен сам принцип используемого вами подхода. Попробую изложить на мой взгяд должно выглядеть решение, а вы ответте где я ошибаюсь. Имеется основная программа, в которой описаны все интерфейсы и которая будет использовать плагины. Все методы, сигналы и слоты общие для какой-то группы железом (напр. Камеры) описаны в интерфейсе и таким образом доступны из основной программы. Может быть масса различных плагинов (sonycam.dll, axiscam.dll) о которых основная программа на этапе компиляции ничего не знает, но которые может использовать благодаря тому что сигналы и слоты их описаны в интерфейсе. Можно конечно создать доп. класс который будет содержать все эти общие сигналы и слоты и отнаследрваться от него но чем этот подход лучше и в чем тогда предназначение интерфейса?
Записан
andrew.k
Гость
« Ответ #25 : Август 21, 2012, 01:02 »

Можно конечно создать доп. класс который будет содержать все эти общие сигналы и слоты и отнаследрваться от него но чем этот подход лучше и в чем тогда предназначение интерфейса?
Об этом и речь. Этот доп класс и есть CommonCamera в примерах.
Уже ведь обсудили этот вопрос.

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

Может спецы 80 уровня выскажут свое мнение? Без иронии, Пантер, Igors и другие? Константина не упоминаю, т.к. еще не прочитал внимательно тред на 4 страницах по этому поводу. Не успел. У него вообще другой подход.
По-моему разницы вообще 0, а три класса это на 50% больше чем два)
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #26 : Август 21, 2012, 08:04 »

Все методы, сигналы и слоты общие для какой-то группы железом (напр. Камеры) описаны в интерфейсе и таким образом доступны из основной программы.
Мы путаемся в терминологии. Интерфейс с точки зрения С++ - класс, состоящий исключительно из абстрактных методов. У него не может быть сигналов и слотов, поскольку они - принадлежность QObject.

Я уже цитировал документацию Qt про плагины и роль интерфейсов в них.
В исходниках Qt из 155 *.h файлов со словом Q_INTERFACE в качестве интерфейса в 154 случаях выступает "голый" класс из набора абстрактных виртуальных методов.
Правда есть один - demos\mobile\quickhit\plugins\levelplugininterface.h в котором интерфейсный класс является потомком QObject, но никаких сигналов/слотов в нём нет, так что зачем это сделано - мне не ведомо.

Если у тебя всё работает и без них (т.е. интерфейс в твоём понимании - это объект, порождённый от QObject и содержащий некий набор абстрактных методов) и тебя это устраивает - можешь не заморачиваться "кошерными" подходами.
« Последнее редактирование: Август 21, 2012, 08:24 от xokc » Записан
andrew.k
Гость
« Ответ #27 : Август 21, 2012, 11:19 »

Все методы, сигналы и слоты общие для какой-то группы железом (напр. Камеры) описаны в интерфейсе и таким образом доступны из основной программы.
Мы путаемся в терминологии. Интерфейс с точки зрения С++ - класс, состоящий исключительно из абстрактных методов. У него не может быть сигналов и слотов, поскольку они - принадлежность QObject.
Хорошо, а если не использовать терминологию с++. Ну назовем этот класс не CameraInterface, а, например, BaseCamera и не будем говорить, что это не с++ интерфейс, а скажем, что это просто абстрактный класс. Что-то изменится? Кошерности прибавится?

UPD. Черт. Получится формально мы не сможем использовать Q_DECLARE_INTERFACE Улыбающийся

Если у тебя всё работает и без них (т.е. интерфейс в твоём понимании - это объект, порождённый от QObject и содержащий некий набор абстрактных методов) и тебя это устраивает - можешь не заморачиваться "кошерными" подходами.
UPD. Посмотрел. У нас в проекте используются оба подхода Улыбающийся Все работает.

В общем ОК.
« Последнее редактирование: Август 21, 2012, 11:38 от andrew.k » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Август 21, 2012, 11:35 »

Пантер, Igors и другие?
Если сам с этим не работал, то лучше помолчать и послушать Улыбающийся

Прочитав тему непонятно в чем проблема. Ну напр класс QAbstractButton сидит в dll и никаких moc в проекте не создает, но сигналы и слоты имеет. Про BasicInterface ничего не знаю, но интерфейсный метод может вернуть указатель на такой объект - ну и крутить с ним слоты/сигналы. Не вижу здесь никаких неудобств, а может так и повыгоднее - разные плагины, разные сигналы
Записан
andrew.k
Гость
« Ответ #29 : Август 21, 2012, 11:45 »

Пантер, Igors и другие?
Если сам с этим не работал, то лучше помолчать и послушать Улыбающийся

Прочитав тему непонятно в чем проблема. Ну напр класс QAbstractButton сидит в dll и никаких moc в проекте не создает, но сигналы и слоты имеет.
Потому что все это уже "сидит" в самой dll.

Про BasicInterface ничего не знаю, но интерфейсный метод может вернуть указатель на такой объект - ну и крутить с ним слоты/сигналы. Не вижу здесь никаких неудобств, а может так и повыгоднее - разные плагины, разные сигналы
Что ж хорошего будет в том, что если все плагины будут по-разному себя вести?
Они на то и плагины, чтобы интерфейсно выглядеть одинаково для ПО.
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.151 секунд. Запросов: 23.