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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: pimpl. Почему работают сигналы из приватного класса? [РЕШЕНО]  (Прочитано 11701 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Февраль 05, 2010, 16:29 »

Доброго времени!

Я сделал небольшой примерчик в котором в приватном классе не унаследованном ни от кого в приватной секции имеется указатель на QTimer.
Код:
#ifndef MYCLASS_P_H
#define MYCLASS_P_H

#include "myclass.h"

class QTimer;
class MyClassPrivate
{
    Q_DECLARE_PUBLIC(MyClass);
public:
    MyClassPrivate();
    virtual ~MyClassPrivate();

    void start();
    void _q_print();

    MyClass * q_ptr;
private:
    int cnt;
    QTimer *timer;
};

#endif // MYCLASS_P_H

И если сделать код, который у меня в примерчике - то можно подключаться к сигналам из приватного класса! О_О

Или я что-то недопонял в концепции.. или я вообще недопонял Улыбающийся

1. Почему работают сигналы, ведь приватный клас не унаследован от QObject и в нем нет макроса Q_OBJECT? (про слоты с префиксом _q_ в приватных классах я в курсе)
2. Можно ли кодить применяя этот подход?

Проект в аттаче
« Последнее редактирование: Февраль 18, 2010, 18:21 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Февраль 05, 2010, 16:40 »

что-то я не вижу сигналов ни в одном из классов
Записан

Юра.
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Февраль 05, 2010, 16:42 »

Цитировать
что-то я не вижу сигналов ни в одном из классов
ну от QTaimer-a сигналы Улыбающийся
timer же находится в приватном классе -> по идее сигналы от него не должны обрабатываться
« Последнее редактирование: Февраль 05, 2010, 16:44 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
BRE
Гость
« Ответ #3 : Февраль 05, 2010, 16:43 »

1. Почему работают сигналы, ведь приватный клас не унаследован от QObject и в нем нет макроса Q_OBJECT? (про слоты с префиксом _q_ в приватных классах я в курсе)
2. Можно ли кодить применяя этот подход?
Ну так ты же используешь:
Q_PRIVATE_SLOT
и moc этого пропустить не может.  Улыбающийся
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Февраль 05, 2010, 16:47 »

Цитировать
Ну так ты же используешь:
Q_PRIVATE_SLOT
и moc этого пропустить не может.
Ну я так понял, что эта фича делает из _q_print() слот... Но каким образом это относится к сигналам от таймера?
Если я сделаю слот в паблик классе MyClass и сделаю коннект - то тоже будет работать!

Прицепил аттач новый
« Последнее редактирование: Февраль 05, 2010, 16:52 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Февраль 05, 2010, 16:50 »

да собственно сигналы от таймера не вызывают удивления.
мне например непонятно как соединение осуществляется для класса не наследника QObject.
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Февраль 05, 2010, 16:53 »

так стоп.
полная запись вот такая:
q->connect(timer, SIGNAL(timeout()), q, SLOT(_q_print()));
где q - наследник QObject и в нём указан макрос Q_OBJECT
Записан

Юра.
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Февраль 05, 2010, 16:54 »

Цитировать
да собственно сигналы от таймера не вызывают удивления.
И? Поделитесь секретом! Улыбающийся В чем "фишка" ? В том что parent у таймера это q ?

Цитировать
мне например непонятно как соединение осуществляется для класса не наследника QObject.
в смысле?
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Февраль 05, 2010, 16:58 »

Цитировать
так стоп.
полная запись вот такая:
q->connect(timer, SIGNAL(timeout()), q, SLOT(_q_print()));
где q - наследник QObject и в нём указан макрос Q_OBJECT

ааа.. начинает доходить!

Ну так значит такой код (идея) имеют место на существование? т.е. в том смысле, что указатели на объекты которые должны емиттить сигналы расположены в приватном классе?
т.е.
Код:
class MyClassPrivate
{
....
....
....
private:
    int cnt;
    QTimer *timer; // вот про это я имею ввиду!!
};

просто я нигде в примерах и исходниках Qt4 не встречал такого (или просто не попалось на глаза) и мне нужно именно так реализовать решение, вот я и спрашиваю Улыбающийся
« Последнее редактирование: Февраль 05, 2010, 17:09 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #9 : Февраль 05, 2010, 17:09 »

>>В чем "фишка" ? В том что parent у таймера это q ?
родитель не причём, у QTimer'а есть сигнал и он посылается при внутреннем событии таймера, независимо ни отчего (если их явно не блокировать).
Сигналы и слоты реализуют идею компонентного программирования, т.е. компонент (QTimer) максимально автономен.
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Февраль 05, 2010, 17:11 »

В целом такой подход (без наследования от QObject) я считаю плохим, т.к. макрос Q_PRIVATE_SLOT отсутствует в открытом описании API, т.е. его нет в Assistant'е
Записан

Юра.
BRE
Гость
« Ответ #11 : Февраль 05, 2010, 17:12 »

Цитировать
так стоп.
полная запись вот такая:
q->connect(timer, SIGNAL(timeout()), q, SLOT(_q_print()));
где q - наследник QObject и в нём указан макрос Q_OBJECT

ааа.. начинает доходить!
На самом деле не обязательно использовать q->connect.
connect это статический метод QObject, т.е. можно просто
QObject::connect( ... );
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #12 : Февраль 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.
connect это статический метод QObject, т.е. можно просто
QObject::connect( ... );
в исходниках Qt я только что заметил, что делают именно q->connect()!

О_О в общем пока непонятно.. неразбериха
Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #13 : Февраль 05, 2010, 19:46 »

>>Почему?
Дык, яж написал:
"...т.к. макрос Q_PRIVATE_SLOT отсутствует в открытом описании API, т.е. его нет в Assistant'е"
Завтра троли переделают потраха, и ты будешь плакать
Записан

Юра.
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #14 : Февраль 09, 2010, 12:08 »

там 90% макросов нет. и например они сами его юзают в креаторе
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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