Название: pimpl. Почему работают сигналы из приватного класса? [РЕШЕНО] Отправлено: kuzulis от Февраль 05, 2010, 16:29 Доброго времени!
Я сделал небольшой примерчик в котором в приватном классе не унаследованном ни от кого в приватной секции имеется указатель на QTimer. Код: #ifndef MYCLASS_P_H И если сделать код, который у меня в примерчике - то можно подключаться к сигналам из приватного класса! О_О Или я что-то недопонял в концепции.. или я вообще недопонял :) 1. Почему работают сигналы, ведь приватный клас не унаследован от QObject и в нем нет макроса Q_OBJECT? (про слоты с префиксом _q_ в приватных классах я в курсе) 2. Можно ли кодить применяя этот подход? Проект в аттаче Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: lit-uriy от Февраль 05, 2010, 16:40 что-то я не вижу сигналов ни в одном из классов
Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: kuzulis от Февраль 05, 2010, 16:42 Цитировать что-то я не вижу сигналов ни в одном из классов ну от QTaimer-a сигналы :)timer же находится в приватном классе -> по идее сигналы от него не должны обрабатываться Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: BRE от Февраль 05, 2010, 16:43 1. Почему работают сигналы, ведь приватный клас не унаследован от QObject и в нем нет макроса Q_OBJECT? (про слоты с префиксом _q_ в приватных классах я в курсе) Ну так ты же используешь:2. Можно ли кодить применяя этот подход? Q_PRIVATE_SLOT и moc этого пропустить не может. :) Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: kuzulis от Февраль 05, 2010, 16:47 Цитировать Ну так ты же используешь: Ну я так понял, что эта фича делает из _q_print() слот... Но каким образом это относится к сигналам от таймера?Q_PRIVATE_SLOT и moc этого пропустить не может. Если я сделаю слот в паблик классе MyClass и сделаю коннект - то тоже будет работать! Прицепил аттач новый Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: lit-uriy от Февраль 05, 2010, 16:50 да собственно сигналы от таймера не вызывают удивления.
мне например непонятно как соединение осуществляется для класса не наследника QObject. Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: lit-uriy от Февраль 05, 2010, 16:53 так стоп.
полная запись вот такая: q->connect(timer, SIGNAL(timeout()), q, SLOT(_q_print())); где q - наследник QObject и в нём указан макрос Q_OBJECT Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: kuzulis от Февраль 05, 2010, 16:54 Цитировать да собственно сигналы от таймера не вызывают удивления. И? Поделитесь секретом! :) В чем "фишка" ? В том что parent у таймера это q ?Цитировать мне например непонятно как соединение осуществляется для класса не наследника QObject. в смысле?Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: kuzulis от Февраль 05, 2010, 16:58 Цитировать так стоп. полная запись вот такая: q->connect(timer, SIGNAL(timeout()), q, SLOT(_q_print())); где q - наследник QObject и в нём указан макрос Q_OBJECT ааа.. начинает доходить! Ну так значит такой код (идея) имеют место на существование? т.е. в том смысле, что указатели на объекты которые должны емиттить сигналы расположены в приватном классе? т.е. Код: class MyClassPrivate просто я нигде в примерах и исходниках Qt4 не встречал такого (или просто не попалось на глаза) и мне нужно именно так реализовать решение, вот я и спрашиваю :) Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: lit-uriy от Февраль 05, 2010, 17:09 >>В чем "фишка" ? В том что parent у таймера это q ?
родитель не причём, у QTimer'а есть сигнал и он посылается при внутреннем событии таймера, независимо ни отчего (если их явно не блокировать). Сигналы и слоты реализуют идею компонентного программирования, т.е. компонент (QTimer) максимально автономен. Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: lit-uriy от Февраль 05, 2010, 17:11 В целом такой подход (без наследования от QObject) я считаю плохим, т.к. макрос Q_PRIVATE_SLOT отсутствует в открытом описании API, т.е. его нет в Assistant'е
Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: BRE от Февраль 05, 2010, 17:12 Цитировать так стоп. полная запись вот такая: q->connect(timer, SIGNAL(timeout()), q, SLOT(_q_print())); где q - наследник QObject и в нём указан макрос Q_OBJECT ааа.. начинает доходить! connect это статический метод QObject, т.е. можно просто QObject::connect( ... ); Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: kuzulis от Февраль 05, 2010, 18:12 Цитировать В целом такой подход (без наследования от QObject) я считаю плохим, т.к. макрос Q_PRIVATE_SLOT отсутствует в открытом описании API, т.е. его нет в Assistant'е Почему? хм, а вот в блоге: http://habrahabr.ru/blogs/qt_software/76506/ автор говорит что: Цитировать Приватные слоты — это механизм дополняющий функционал d-указателей. Он позволяет реализовать слоты для приватного класса, даже если он не является наследником от QObject (обычно он им и не является), но для этого публичный класс должен быть наследником от QObject. Тоесть по факту создается некий приватный слот в публичном классе и он непосредственно дергает нужный метод приватного класса. Зачем это нужно? Ну рассмотрим на примере. Есть класс QAbstractScrollArea. Он просто отображает некий виджет (viewport) и обеспечивает прокрутку. Прокрутка обеспечивается с помощью двух экземпляров класса QScrollBar. Сами эти скролбары он хранит в приватном классе. Теперь проблемма: как подключить сигнал от скроллбара об изменение его позиции с классом QAbstractScrollAreaPrivate, ведь он не является QObject'ом? Сделать его наследником от QObject — лучше не делайте это :-) . Можно сделать слот в публичном классе и повесить на него, то в таком случае это не очень красиво — так как наружу выходят слоты от внутренней реализации. Вот ту Qt-шниками был придуман достаточно разумный и элегантный подход — приватные слоты. да и в исходниках Qt4 приватные классы НЕ наследуются от QObject! Цитировать На самом деле не обязательно использовать q->connect. в исходниках Qt я только что заметил, что делают именно q->connect()!connect это статический метод QObject, т.е. можно просто QObject::connect( ... ); О_О в общем пока непонятно.. неразбериха Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: lit-uriy от Февраль 05, 2010, 19:46 >>Почему?
Дык, яж написал: "...т.к. макрос Q_PRIVATE_SLOT отсутствует в открытом описании API, т.е. его нет в Assistant'е" Завтра троли переделают потраха, и ты будешь плакать Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: Авварон от Февраль 09, 2010, 12:08 там 90% макросов нет. и например они сами его юзают в креаторе
Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: ритт от Февраль 18, 2010, 16:59 не переделают завтра...и в 5.0 не переделают, скорее всего...
сам часто использую данную группу макросов и пока что не собираюсь плакать про сигналы от таймера - я даже не сразу понял суть "открытия"...но это - полная чушь :) то, что таймер задекларирован в приватной секции не-куобжэкта, не играет абсолютно никакой роли. ровно с таким же успехом сигналы будут испускаться и из мэйна (если создать кореапп и запустить очередь) Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: kuzulis от Февраль 18, 2010, 18:20 Ок, спс за консультэйшен :)
Название: Re: pimpl. Почему работают сигналы из приватного класса? Отправлено: SABROG от Февраль 21, 2010, 01:44 там 90% макросов нет. и например они сами его юзают в креаторе На самом деле код QtCreator'a оставил удручающее впечатление. Тролли вовсю используют приватные/недокументированные вещи из исходников Qt вместо того, чтобы исправить саму библиотеку и документацию сделав их публичными. Это лишь говорит о том, что сами тролли при создании QtCreator'a столкнулись с задачами, которые либо сложно либо невозможно решить публичным API Qt. Кстати запросто можно испустить сигнал любого объекта как буд-то он сам его сгенерил: Код
Обратите внимание, я нигде не запускаю таймер, а он приходит как QTimer::singleShot(0, &object, SLOT(timeout()), так как был искусственно сгенерирован. На деле, если попытаться написать такое: Код
То Qt выдаст в консоль ошибку о том, что сигнал является protected. Но конструкция на самом деле рабочая. Задача усложняется лишь тем, что макрос "slots" помещает сигналы всегда в protected секцию и единственный способ сделать сигнал публичным это использовать Q_SIGNAL: Код: public: Но тут может быть проблема, если в приложении используется boost или другая библиотека, которая реализует собственную систему сигналов и слотов. Если так уже нужно чтобы объект генерил сигнал, но по запросу извне, то в случае с собственным классом лучше использовать публичный метод обертку, а в случае с чужими объектами решение я привел выше. Название: Re: pimpl. Почему работают сигналы из приватного класса? [РЕШЕНО] Отправлено: ритт от Февраль 21, 2010, 08:59 > На самом деле код QtCreator'a оставил удручающее впечатление. Тролли вовсю используют приватные/недокументированные вещи из исходников Qt вместо того, чтобы исправить саму библиотеку и документацию сделав их публичными. Это лишь говорит о том, что сами тролли при создании QtCreator'a столкнулись с задачами, которые либо сложно либо невозможно решить публичным API Qt.
будь добр, приведи несколько примеров Название: Re: pimpl. Почему работают сигналы из приватного класса? [РЕШЕНО] Отправлено: SABROG от Февраль 21, 2010, 16:52 /src/libs/utils/consoleprocess_win.cpp
Код
/src/libs/qtconcurrent/multitask.h Код
/src/plugins/qt4projectmanager/qtmodulesinfo.cpp Код
|