Russian Qt Forum
Апреля 21, 2025, 22:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Разграничение передачи сигнала в несколько потоков  (Прочитано 13649 раз)
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.078 секунд. Запросов: 20.