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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QtService и макрос Q_OBJECT  (Прочитано 7540 раз)
lighting
Гость
« : Ноябрь 23, 2010, 11:04 »

Писал на Qt службу для Win с использованием QtService и столкнулся с такой проблемой - если класс наследник от QtService также отнаследуется от QObject то при сборке появляется ругань на vtable и сборка обламывается. Фактически это означает что воспользоваться connect для записи событий в eventlog можно только обходными путями - создав специальный класс в отдельном файле и передавая ему ссылку на класс сервиса, слоты для записи событий также надо писать в этом отдельном классе. Решение хоть и рабочее но какое-то корявое (приходится объявлять практически все переменные класса-сервиса как public и т.п.) и мне не нравится. Возникала-ли у кого-нибудь схожая проблема, и если да то как вы ее решали?
Qt 4.7, qtservice-2.6-opensource.
Записан
BRE
Гость
« Ответ #1 : Ноябрь 23, 2010, 11:57 »

А для чего логеру предоставлять весь функционал сервиса? Может лучше сервису предоставить функционал логера? Также легко будет реализовать разные варианты логирования (в файл, в базу данных, отправлять по сети, ...).
Записан
lighting
Гость
« Ответ #2 : Ноябрь 23, 2010, 12:14 »

Я не это имел ввиду - задача у меня достаточно простая, поэтому я хотел использовать только один класс, в котором будет и функционал сервиса и логирование его работы. Но ввиду ошибки vtable пришлось писать отдельный класс, да еще и выносить его в отдельные *.h *.cpp
Вопрос собственно в том можно-ли как-то эту ошибку обойти и обойтись одним классом?
Записан
asvil
Гость
« Ответ #3 : Ноябрь 23, 2010, 13:05 »

QtServiceBase::instance() частично решит проблему. Очень скоро готовиться обновление log4qt с поддержкой eventlog\syslog и вы сможете чуть более обширно вести логи.
Записан
BRE
Гость
« Ответ #4 : Ноябрь 23, 2010, 14:30 »

пришлось писать отдельный класс, да еще и выносить его в отдельные *.h *.cpp
Неужели это вызвало столько сложностей?  Строит глазки
Для ООП в целом и C++ в частности, создание необходимых классов это скорее норма, чем наказание.
А желание загнать всю программу в один класс как раз говорит о плохой архитектуре приложения. При ООП программы состоят из объектов разных классов, взаимодействующих друг с другом.
Записан
lighting
Гость
« Ответ #5 : Ноябрь 23, 2010, 15:36 »

Для ООП в целом и C++ в частности, создание необходимых классов это скорее норма, чем наказание.
В том-то и дело что дополнительный класс не только не видится мне необходимым, но наоборот - кажется совершенно излишним.
Не хотел вдаваться в детали конкретной реализации но видимо придется - весь класс сервиса только и делает что объявляет пару переменных другого класса (уже отлаженных и реализующих весь необходимый функционал), осуществляет их инициализацию, подключение/отключение(работа по сети) да еще должен был в eventlog  писать сообщения о незапланированных остановках. Но последнее реализовать в рамках этого класса не удалось, о чем собственно и тема.
Записан
BRE
Гость
« Ответ #6 : Ноябрь 23, 2010, 16:00 »

Ну как-же он может быть излишним.  Улыбающийся
Есть два класса, объекты которых выполняют какие-то действия взаимодействуя друг с другом. Каждый выполняет свою работу. Потребовалось добавить третью работу - логирование. Создаем класс, который умеет выполнять эту работу и встраиваем объект этого класса в систему. По прежнему все объекты занимаются своим делом, используя определенные связи и не лезут в душу друг к другу.
Записан
lighting
Гость
« Ответ #7 : Ноябрь 23, 2010, 16:49 »

Ну я уже прям и не знаю как еще объяснить... наверное вот так:
Код
C++ (Qt)
class Service : public QtService<QCoreApplication>
{
public:
   Service(int argc, char **argv)
       : QtService<QCoreApplication>(argc, argv, "Camera control service");
 
   RealCU2000M realt;
   Sony sony;
    ...
 
protected:
   void start();
   void stop();
};
 
Так вот - два класса это RealCU2000M и Sony. Для превращения их в службу я добавил класс Service, но в этом классе я не могу обрабатывать сигналы от двух рабочих классов, для чего пришлось лепить еще один класс - Logger:
Код
C++ (Qt)
class Logger : public QObject
{
   Q_OBJECT
 
public:
   Logger(Service*, QObject *parent = 0);
...
private:
   Service *service;
};
 
Инициализировать его вот так:
Код
C++ (Qt)
Logger::Logger(Service *serv, QObject *parent) : QObject(parent)
{
   service = serv;
}
и вот таким извращенным способом записывать события в eventlog, добавляя слоты в класс logger:
Код
C++ (Qt)
service->logMessage("Service started", QtServiceBase::Information);
Если вам по прежнему все кажется оптимальным и логичным то я умываю руки.
« Последнее редактирование: Ноябрь 23, 2010, 16:54 от lighting » Записан
BRE
Гость
« Ответ #8 : Ноябрь 23, 2010, 17:02 »

А почему так?
Почему не добавить в нужные классы, например, сигнал sendInfo( const QString &str ) и не соединить его со слотом write( const QString &str ) объекта logger?
Или не передавать ссылку на объект logger в объекты realt, sony?
Или не сделать из логера singleton?
Или ...
Записан
lighting
Гость
« Ответ #9 : Ноябрь 23, 2010, 17:44 »

У меня устойчивое впечатление что мы друг друга не понимаем и объясняем каждый что-то свое... Я вообще не понимаю зачем нужен класс Logger (ну кроме того чтобы обойти ошибку сборки), а вы предлагаете какие-то альтернативные варианты его использования...
Записан
BRE
Гость
« Ответ #10 : Ноябрь 23, 2010, 18:26 »

У меня устойчивое впечатление что мы друг друга не понимаем и объясняем каждый что-то свое... Я вообще не понимаю зачем нужен класс Logger (ну кроме того чтобы обойти ошибку сборки), а вы предлагаете какие-то альтернативные варианты его использования...
У меня тоже сложилось такое впечатление.

Записан
asvil
Гость
« Ответ #11 : Ноябрь 23, 2010, 18:54 »

Ох, ну если Вам не нужен Logger, то тогда не обращайте внимания на мой пост выше. Вы можете случайно не понять существование целого проекта.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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