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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Сигналы, слоты + передача с помощью них данных?  (Прочитано 27107 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

доброго дня!

= случай №1 = (передаем с помощью сигналов и слотов между объектов ДАННЫЕ!)

main.cpp
Код:
#include <QtCore>
#include <QCoreApplication>

#include "ab.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    A *cA = new A();
    B *cB = new B();
    QObject::connect(cA, SIGNAL(sgFromA(int)), cB, SLOT(slotB(int))); //тут по значению передача данных происходит!!!
    cA->slotA();//запускаем таймер
    return app.exec();
}
ab.h
Код:
#ifndef AB_H
#define AB_H
#include <QDebug>
#include <QTimer>

class A : public QObject
{
    Q_OBJECT
signals:
    void sgFromA(int data);
public:
    A() { cnt = 0; }
public slots:
    void slotA() {//выполняем этот слот сами один раз в main
        qWarning() << "A::slotA() -> GO GO GO";
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(slotA1()));
        timer->start(1000);
    }
    void slotA1() {//этот слот класса А будет емиттить сигнал с данными для слота В
            ++cnt;
            qWarning() << "A::slotA1() -> sended CNT = " << cnt;
            emit sgFromA(cnt);//здесь передаем ЗНАЧЕНИЕ переменной!
    }
private:
    int cnt;//типа счетчик
};

class B: public QObject
{
    Q_OBJECT
public slots:
    void slotB(int data) {//этот слот класса В будет принимать сигнал от класса А с данными
        qWarning() << "B::slotB() -> received CNT = " << data;
    }
};
#endif // AB_H

= случай №2 = (передаем с помощью сигналов и слотов между объектов УКАЗАТЕЛИ НА ДАННЫЕ!)

main.cpp
Код:
#include <QtCore>
#include <QCoreApplication>

#include "ab.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    A *cA = new A();
    B *cB = new B();
    QObject::connect(cA, SIGNAL(sgFromA(int *)), cB, SLOT(slotB(int *)));
    cA->slotA();//запускаем таймер
    return app.exec();
}
ab.h
Код:
#ifndef AB_H
#define AB_H
#include <QDebug>
#include <QTimer>

class A : public QObject
{
    Q_OBJECT
signals:
    void sgFromA(int *data);
public:
    A() { cnt = 0; }
public slots:
    void slotA() {//выполняем этот слот сами один раз в main
        qWarning() << "A::slotA() -> GO GO GO";
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(slotA1()));
        timer->start(1000);
    }
    void slotA1() {//этот слот класса А будет емиттить сигнал с данными для слота В
            ++cnt;
            qWarning() << "A::slotA1() -> sended CNT = " << cnt;
            emit sgFromA(&cnt); //здесь передаем АДРЕС переменной!
    }
private:
    int cnt;//типа счетчик
};

class B: public QObject
{
    Q_OBJECT
public slots:
    void slotB(int *data) {//этот слот класса В будет принимать сигнал от класса А с данными
        qWarning() << "B::slotB() -> received CNT = " << *data;//
    }
};
#endif // AB_H

варианты №1 и №2 работают в конечном счете одинаково, НО:
1. Хотелось бы узнать, а в каком случае после компиляции проекта будут БЫСТРЕЕ обратываться данные и меньше будет использование памяти?
    ( т.е в случае №1 - создается дополнительная переменная int data в которую сначала копируется результат счетчика, потом из нее забирается он,
      а в случае №2 все идет по адресу ... т.е мое ИМХО - что так будет быстрее и меньше памяти будет использоваться)
2. Или это не имеет значения, т.к компилятор все-равно оптимизирует код?
« Последнее редактирование: Февраль 05, 2009, 16:04 от kuzulis » Записан

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

Сообщений: 3880


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

для инта пожалуй все равно, а если посмотреть на то как делают троли, то видно, что для собственных типов данных используют ссылки.
Записан

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

Сообщений: 2812


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

Цитировать
для инта пожалуй все равно, а если посмотреть на то как делают троли, то видно, что для собственных типов данных используют ссылки.
пример в студию! Улыбающийся

------
т.е
1. если я например в качестве данных передаю например QList - то
в классе A писать:
Код:
signals:
    void sgFromA(QList<*MyDataTypes> *data);
в классе B писать:
Код:
public slots:
    void slotB(QList<*MyDataTypes> *data);
в main писать:
Код:
QObject::connect(cA, SIGNAL(sgFromA(QList<*MyDataTypes> *)), cB, SLOT(slotB(QList<*MyDataTypes> *)); 

Непонимающий??

2. а если я передаю какой-то свой тип данных типа структуры или класса то:
в классе A писать:
Код:
signals:
    void sgFromA(MyDataTypes *data);
в классе B писать:
Код:
public slots:
    void slotB(MyDataTypes *data);
в main писать:
Код:
QObject::connect(cA, SIGNAL(sgFromA(MyDataTypes *)), cB, SLOT(slotB(MyDataTypes *)); 

Непонимающий

мне интересно поподробнее это узнать, т.к везде в примерах передают или int или QString.. (из тех примеров что мне попадались)

и еще... а когда целесообразно при передаче параметров писать ключевое слово :
Код:
const

Непонимающий
« Последнее редактирование: Февраль 05, 2009, 16:24 от kuzulis » Записан

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

Сообщений: 3880


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

я говорил не об указателях, а о ссылках:
connect(table->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
         this, SLOT(currentChanged()) );
Записан

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

Сообщений: 2812


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

Цитировать
я говорил не об указателях, а о ссылках:
connect(table->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
         this, SLOT(currentChanged()) );

я ща попробовал с int такое провернуть... работает! Улыбающийся

но все-таки интересно что быстрее...
1. передавать: data
или
2. передавать: *data
или
3. передавать: const &data
Непонимающий
Записан

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

Сообщений: 3880


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

2 и 3 быстрее
Записан

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

Сообщений: 2812


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

Улыбающийся ну это вроде понятно..
а вот между 2 и 3 ?
Записан

ArchLinux x86_64 / Win10 64 bit
ритт
Гость
« Ответ #7 : Февраль 05, 2009, 18:31 »

эмм...не забываем, что для {,Blocking}QueuedConnection все данные копируются через QMetaType::create(), а потом кастятся из void* в требуемый тип...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Февраль 06, 2009, 08:27 »

Цитировать
эмм...не забываем, что для {,Blocking}QueuedConnection все данные копируются через QMetaType::create(), а потом кастятся из void* в требуемый тип...

т.е? и что это значит? Улыбающийся

(т.е. на что это сказывается и т.п)

ЗЫ: только по рабоче-крестьянски пжлста...
« Последнее редактирование: Февраль 06, 2009, 08:35 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #9 : Февраль 06, 2009, 12:15 »

Значит что данные где-то временно сохранятся и будут доставлены в нужный слот позже. То-есть произойдёт многократное копирование. К счастью большинство классов что передаются через сигнал-слот - Implicitly Shared, то-есть операции копирования таких данных атомарны.
Записан
Steven_Orko
Гость
« Ответ #10 : Февраль 06, 2009, 12:42 »

2 и 3 быстрее
Да ну?? Правда? А если так:
Код:
char data[2];

Указатель на data для 32bit занимает 4 байта, а для 64 сами знаете....
Тоже самое и со ссылкой, которая есть ничто иное как разыименованный указатель.
И что в итоге быстрее?

Я к тому, что надо оговаривать конкретный тип данных data. ИМХО, для POD-типов не имеет значение,  как их передавать: по ссылке, значению или указателю, если, конечно, это не огромный цикл копирования...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #11 : Февраль 06, 2009, 12:50 »

так в каких случаях будет временно копирование происходить а в каких нет и если будет - то сколько раз оно будет происходить за передачу?

1. Я передаю через сигнал-слот переменные типов: int,byte,bool - да/нет и сколько раз
2. Я передаю через сигнал-слот ссылку переменной типов: const int &,const byte &,const bool & (и т.п.) - да/нет и сколько раз
3. Я передаю через сигнал-слот ссылку строки типа: const QString & - да/нет и сколько раз
4. Я передаю через сигнал-слот переменную типа QObject (в общем случае): QObject  - да/нет и сколько раз
5. Я передаю через сигнал-слот ссылку типа QObject (в общем случае): const QObject &  - да/нет и сколько раз
6. Я передаю через сигнал-слот свою переменную типа TUserDadaType (в общем случае являющуюся просто классом или структурой, не наследованной ни от чего):
                                                         TUserDadaType - да/нет и сколько раз
6. Я передаю через сигнал-слот свою ссылку переменной типа TUserDadaType (в общем случае являющуюся просто классом или структурой, не наследованной ни от чего):
                                                         const TUserDadaType & - да/нет и сколько раз

ЗЫ: я спрашиваю, потому что у меня приложение собирается быть "большим", т.е многопоточным и должен большой объем данных обрабатываться + ко всему, нужно все это делать как можно быстрее!! т.е скорость должна быть на максимуме! и передачу данных между объектами приложения я пока планирую делать с помощью сигналов-слотов! т.е каждая операция копирования , пересылки и т.п у меня на счету! Улыбающийся
« Последнее редактирование: Февраль 06, 2009, 12:52 от kuzulis » Записан

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

Сообщений: 2812


Просмотр профиля
« Ответ #12 : Февраль 06, 2009, 12:54 »

Цитировать
И что в итоге быстрее?
я тоже хочу это знать! Улыбающийся
Цитировать
Тоже самое и со ссылкой, которая есть ничто иное как разыименованный указатель.
так сколько затрачивается шагов в среднем? как это определить?
если:
1. я передаю переменную с помошью сигнал - слот
2. я передаю ссылку с помошью сигнал - слот
3. я передаю указатель с помощью сигнал-слот
« Последнее редактирование: Февраль 06, 2009, 12:58 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #13 : Февраль 06, 2009, 13:16 »

Дак, а с чего вы решили что количество копирований должно меняться в зависимости от того что передаётся? В случае когда вызов слота синхронный - данные копируются только по стеку. Какая разница сколько времени на это тратится, если новая память в куче не выделяется? Большинство данных копируются одной операцией, а Implicitly Shared классы вообще копируются атомарно. Если вам критично сколько происходит накладных расходов на вызов сигнала - подсоедините его к пустому слоту и замерьте несколько вызовов в цикле:

Код
C++ (Qt)
connect( SIGNAL(mySignal(int)), this, SLOT(mySlot(int)) );
QTime time = QTime::currentTime();
for ( int i = 0; i < 1000000; ++i )
 emit mySignal( 0 );
qDebug() << "Time for one emit: " << (float)time.elapsed()/1000000;
...
void MyClass::mySlot( int )
{
 // empty
}

Добавьте количество аргументов в сигнал/слот и протестируйте. О результатах доложите.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #14 : Февраль 06, 2009, 14:00 »

нет, это не то... в этом примере оценивается только время емиттинья сигнала...

а мне (нам) необходимо оценить время, прошедшее от еммитинья сигнала (передачи переменной) до приема сигнала (до того как эту переменную в слоте прочитали)...
т.е время цикла: обработка-передача-прием-обработка

вопрос: есть ли в QT какая нить ф-я для подсчета кол-ва тиков процессора и т.п., т.к оценить время не представляется возможным  т.к. оно оч мало
« Последнее редактирование: Февраль 06, 2009, 14:03 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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