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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Разграничение передачи сигнала в несколько потоков  (Прочитано 13411 раз)
thechicho
Гость
« : Ноябрь 06, 2011, 11:17 »

Из главного потока необходимо посылать сигнал в дочерние.

потоки создаются:
Код
C++ (Qt)
for (int i = 0; i < N; i++ {
NewThread *thread = new NewThread(this);
connect(this, SIGNAL(StringSignal(QString &)), thread, SLOT(StringSlot(QString &)));
}

сигнал посылается:
Код
C++ (Qt)
void anySlot()
{
   QString test= "test";
   emit StringSignal(test);
}

таким образом, сигнал пойдет во все потоки?
а как разграничить можно? чтобы сигнал посылался в конкретный поток. типа
Код
C++ (Qt)
emit StringSignal(test, threadN);
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Ноябрь 06, 2011, 11:36 »

Присоединять сигнал только к этому слоту (можно через сигнал маппер, получится примерно то, что вы описали).
Ну или QMetaObject::invoke вместо эмита.
Записан
Ubuntu_linux
Гость
« Ответ #2 : Ноябрь 06, 2011, 20:15 »

Кстати, сигнал можно конектить к сигналу!
Записан
thechicho
Гость
« Ответ #3 : Ноябрь 07, 2011, 11:22 »

// Присоединять сигнал только к этому слоту (можно через сигнал маппер, получится примерно то, что вы описали).
сорри, не очень понял. вернее совсем не понял. если я создам 10 потоков, для каждого нужно connect и слоты? так не вариант...
поясни, плиз, как это реализуется. или хотя б как сигнал маппер в документации можно найти (как он на английском звучит).

// Кстати, сигнал можно конектить к сигналу!
я знал, я знал!
если серьезно, не представляю как это может помочь.
Записан
Waryable
Гость
« Ответ #4 : Ноябрь 07, 2011, 12:37 »

В сигнале посылайте указатель на поток. В слоте проверяйте указатель и решайте обрабатывать или нет.
Записан
thechicho
Гость
« Ответ #5 : Ноябрь 07, 2011, 13:49 »

сенкс за ваши ответы!
решил сделать по-другому.
передал указатели на QLineEdit  в поток, и прямо оттуда читаю введеный текст, при получении сигнала из главного потока, связанного с указателями QLineEdit.

.h
Код
C++ (Qt)
QList<QLineEdit*> lineEditList;

.cpp
Код
C++ (Qt)
for (int i = 0; i < N; i++ {
QLineEdit *lineEditDialog = new QLineEdit(dialog);
lineEditList<< lineEditDialog;
}
 
for (int i = 0; i < N; i++ {
NewThread *thread = new NewThread(this);
connect(lineEditList[i], SIGNAL(returnPressed()), thread, SLOT(StringSlot()));
}

работает так, как я и хотел Улыбающийся
Записан
JamS007
Гость
« Ответ #6 : Январь 03, 2012, 23:52 »

Привет!
Была аналогичная задача.
Нужно было посылать уведомление в один или несколько потоков из общего пула. Долго копал документацию по этому поводу, в конце концов вот к чему пришел:
В доке сказано, что сигналы между потоками преобразуются в ивенты (QEvent) и обрабатываться exec()-циклом внутри потока, в связи с чем было принято решение реализовать собственный механизм отправки сообщений с помощью QEvent:

У меня уведомление было связано с появлением нового клиента, поэтому класс сообщения об этом так и назван, уж простите за семантику Улыбающийся

Класс сообщения выглядит следующим образом:
Код
C++ (Qt)
class NewClientEvent: public QEvent
{
public:
   static const QEvent::Type ET_NewClientEvent = (QEvent::Type)2000;
   explicit NewClientEvent():
   // ...
};

В классе потока следующим образом переопределена функция event():
Код
C++ (Qt)
bool WorkThread::event(QEvent *event)
{
   if (event && event->type() == NewClientEvent::ET_NewClientEvent){
       // ...
       return true;
   }
   return QThread::event(event);
}

В основном классе создаю потоки таким образом:
Код
C++ (Qt)
mThreadsList = new std::vector<WorkThread*>();
mThreadsList->reserve(idealThreadsCount());
for (int i=0; i<mThreadsList->capacity(); ++i){
   WorkThread *thread = new WorkThread(mRequestsHandler, 0);
   thread->start();
   mThreadsList->push_back(thread);
}

Ну а сообщения посылал так:
Код
C++ (Qt)
QThread *thread = mThreadsPool->nextThread();
if (! thread)
   return;
 
NewClientEvent *event = new NewClientEvent(handle);
QCoreApplication::postEvent(thread, event);

Если отбросить детали моей реализации то должно быть не очень сложно. Надеюсь, кому-нибудь помог.
Записан
andrew.k
Гость
« Ответ #7 : Январь 04, 2012, 00:06 »

сенкс за ваши ответы!
решил сделать по-другому.
передал указатели на QLineEdit  в поток, и прямо оттуда читаю введеный текст, при получении сигнала из главного потока, связанного с указателями QLineEdit.

работает так, как я и хотел Улыбающийся
Жесть. Из других потоков нельзя взаимодействовать с GUI (по-крайней мере так рекомендуется в документации). И если у тебя оно работает, это до поры до времени, а как сломается, устанешь искать баги.
invokeMethod то, что тебе нужно, посылай в нужный поток.
Записан
thechicho
Гость
« Ответ #8 : Январь 06, 2012, 17:18 »

да я по-другому сделал.
создал слот в потоке и соединил гуишные элементы с этим слотом. гуи посылает сигнал, в этот слот.
вот и все.
правда, все равно 1 элемент скопировал в поток. есть groupbox, в кот. 2 qradiobutton. указатель на 1 qradiobutton копируется в поток. там проверяется на отмечен. чтобы можно было в режиме реального времени условие поменять... в принципе можно и слот сделать в гуи потоке и в потоки передавать bool переменную, а в этом слоте ее менять... но прогу я писал для себя, так что не заморачиваюсь на этот счет. ну упадет при проверке isChecked ()  (во что нео4 верится  Улыбающийся), ну запущу по новой Веселый если вдруг будет часто падать, добавлю в слоте изменение условия.
короче мораль - надо делать проще и чтобы работало Веселый
Записан
andrew.k
Гость
« Ответ #9 : Январь 06, 2012, 17:26 »

да я по-другому сделал.
создал слот в потоке и соединил гуишные элементы с этим слотом. гуи посылает сигнал, в этот слот.
вот и все.
правда, все равно 1 элемент скопировал в поток. есть groupbox, в кот. 2 qradiobutton. указатель на 1 qradiobutton копируется в поток. там проверяется на отмечен. чтобы можно было в режиме реального времени условие поменять... в принципе можно и слот сделать в гуи потоке и в потоки передавать bool переменную, а в этом слоте ее менять... но прогу я писал для себя, так что не заморачиваюсь на этот счет. ну упадет при проверке isChecked ()  (во что нео4 верится  Улыбающийся), ну запущу по новой Веселый если вдруг будет часто падать, добавлю в слоте изменение условия.
короче мораль - надо делать проще и чтобы работало Веселый
Надо делать грамотно и для себя и для других.
Записан
thechicho
Гость
« Ответ #10 : Январь 06, 2012, 17:40 »

надо делать, чтобы работало
надо делать, чтобы работало быстро и стабильно

или 1ое, или второе.
мне по-другому не надо.
пока и 1ое и 2ое получается реализовывать Веселый
« Последнее редактирование: Январь 06, 2012, 17:41 от thechicho » Записан
Akon
Гость
« Ответ #11 : Январь 06, 2012, 21:48 »

2HaySayCheese:
А почему использовали именно события (QEvent); сигнал/слот механизм чем не устроил? Первое сопряжено с синтаксическим оверхедом.
Записан
andrew.k
Гость
« Ответ #12 : Январь 06, 2012, 23:17 »

надо делать, чтобы работало
Вот поэтому у нас все так. Потому что все "делают, чтобы работало".
Записан
thechicho
Гость
« Ответ #13 : Январь 07, 2012, 01:26 »

а как у вас? Подмигивающий
фишка в том, что я пишу, как умею.
мне проги нужны, а не красивый код.
Записан
popper
Гость
« Ответ #14 : Январь 07, 2012, 11:41 »

а тестирование программы принято поручать конечным пользователям
и кто-то все написанное с целью "чтобы работало" должен как-то поддерживать
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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