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

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

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: Сигналы и массив  (Прочитано 34320 раз)
spectre71
Гость
« Ответ #15 : Декабрь 01, 2009, 19:46 »

Опиши чуть подробнее, есть предположение что ты имеешь ввиду, но не совсем уверен.
Не знаю как бы ещё по-подробнее...Просто не хочу приводить ява-код, только лишний раз вводить в заблуждение.
Жму на форме "старт", запускается поток, который клепает множество других (в цикле), которые испускают сигналы. Зачем это дело кинул в отдельный поток? - чтобы легко было управлять, ставить паузы, запускать заново с обнулением счётчика, не тормозила форма при этом цикле и т.п.
Главный поток (который отвечает за gui) принимает сигналы и создаёт gui-объекты, после создания каждого объекта шлёт такой сигнал, чтобы именно нужный поток 3го уровня его подхватил. Затем поток 3 уровня может послать на главный поток другой сигнал (если надо), главный поток ему (и только ему) ответит результатом.

Простой вариант:

1)
В объекте главного потока делаем слот на прием сообщений от второстепенных потоков
Во второстепенных  потоках делаем сигнал для отправки данных главному потоку
Для каждого потока их соединение делаем сразу после его создиния
В слоте главного потока получаем указатель второстепенного  потока через по sender()
2) Для приема данных от главного потока в классе второстепенного делаем.
- Обычный public метод который вызовет объект главного потока (SetData)
- Делаем сигнал(signalSetData) и слот(slotlSetData). Соединяем и в консструкторе потока c флагом Qt::QueuedConnection
- В методе SetData делаем "emit signalSetData" - переправляем данные самому себе
3) Как все вместе работает
- Главный поток получает сигнал от второстепенного
- По sender() получает указатель и приводит его к нужному типу (MyThread* thr = static_cast<MyThread*>(sender())Подмигивающий
- Делает необходимую обработку
- Вызывает непосредственно thr->SetData для отправки данных второстепенному потоку
Записан
niXman
Гость
« Ответ #16 : Декабрь 02, 2009, 19:42 »

Реализовывал ранее подобный класс.
Оформлю, выложу на гугл-код, дам ссылку. Но класс на С++.
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #17 : Декабрь 03, 2009, 11:18 »

- Вызывает непосредственно thr->SetData для отправки данных второстепенному потоку
А что, можно отослать сигнал конкретному второстепенному потоку (пусть даже имея его как сендера)? Как?
« Последнее редактирование: Декабрь 03, 2009, 11:38 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Декабрь 03, 2009, 12:13 »

А что, можно отослать сигнал конкретному второстепенному потоку (пусть даже имея его как сендера)? Как?
Любой потомок QObject знает нитку в которой он создан. Если Вы пошлете ему event, он будет обрабатываться в EventLoop этой нитки. Таким образом у Вас нет проблем "послать потоку", просто посылайте "объекту этого потока" и не видно зачем Вам вообще связываться с какими-то сигналами. 
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #19 : Декабрь 03, 2009, 12:29 »

А что, можно отослать сигнал конкретному второстепенному потоку (пусть даже имея его как сендера)? Как?
Любой потомок QObject знает нитку в которой он создан. Если Вы пошлете ему event, он будет обрабатываться в EventLoop этой нитки. Таким образом у Вас нет проблем "послать потоку", просто посылайте "объекту этого потока" и не видно зачем Вам вообще связываться с какими-то сигналами.  
А можно какой-нибудь простейший пример? Ни разу не работал с QEvent
А сигналы нужны для связи между разными потоками, QEvent это тоже предоставит?
Записан

kubuntu/Win7/x64/NetBeans
spectre71
Гость
« Ответ #20 : Декабрь 03, 2009, 12:38 »

- Вызывает непосредственно thr->SetData для отправки данных второстепенному потоку
А что, можно отослать сигнал конкретному второстепенному потоку (пусть даже имея его как сендера)? Как?

Причем здесь сигнал?
Непосредственный вызов thr->SetData(MyData) из главного потока
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #21 : Декабрь 03, 2009, 13:01 »

А можно какой-нибудь простейший пример? Ни разу не работал с QEvent
А сигналы нужны для связи между разными потоками, QEvent это тоже предоставит?
Сигналы между нитками все равно сводятся к postEvent, т.е. он-то и предоставляет. Псевдокод

Код:
class MyEvent : public QCustomEvent {
public:
  ...
  int mActionID;             //  действие
  QObject * mSender;    // удобно записать посылающего
  ......                         // передаваемые данные
};

В вызывающей нитке
Код:
MyEvent * evt = new MyEvent();
evt->mActionID = ...     // заряжаем данные для передачи
evt->mSender = this;
QAppication::postEvent(theReceiver[threadIndex], evt);  // посылаем объекту нитки с индексом threadIndex

В нитке-получателе
Код:
void MyReceiver::customEvent( QEvent * event )
{
  MyEvent * evt = dynamic_cast <MyEvent *> (event);
  if (!evt) return;
  switch (evt->mActionID) {
    ....
    case ACT_1:
      ...
      postEvent(evt->mSender, reply);   // отвечаем пославшему
      break;
  }
}
« Последнее редактирование: Декабрь 03, 2009, 13:07 от Igors » Записан
BRE
Гость
« Ответ #22 : Декабрь 03, 2009, 13:05 »

Код:
void MyReceiver::customEvent( QEvent * event )
{
  MyEvent * evt = qobject_cast <MyEvent *> (evt);
QEvent не наследник QObject, поэтому qobject_cast работать не должен/не будет.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Декабрь 03, 2009, 13:08 »

Код:
void MyReceiver::customEvent( QEvent * event )
{
  MyEvent * evt = qobject_cast <MyEvent *> (evt);
QEvent не наследник QObject, поэтому qobject_cast работать не должен/не будет.

Спасибо, поправил на dynamic_cast
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #24 : Декабрь 03, 2009, 17:14 »

Простой вариант:

1)
В объекте главного потока делаем слот на прием сообщений от второстепенных потоков
Во второстепенных  потоках делаем сигнал для отправки данных главному потоку
Для каждого потока их соединение делаем сразу после его создиния
В слоте главного потока получаем указатель второстепенного  потока через по sender()
2) Для приема данных от главного потока в классе второстепенного делаем.
- Обычный public метод который вызовет объект главного потока (SetData)
- Делаем сигнал(signalSetData) и слот(slotlSetData). Соединяем и в консструкторе потока c флагом Qt::QueuedConnection
- В методе SetData делаем "emit signalSetData" - переправляем данные самому себе
3) Как все вместе работает
- Главный поток получает сигнал от второстепенного
- По sender() получает указатель и приводит его к нужному типу (MyThread* thr = static_cast<MyThread*>(sender())Подмигивающий
- Делает необходимую обработку
- Вызывает непосредственно thr->SetData для отправки данных второстепенному потоку

Сделал. Всё так, но в методе (слоте) главного потока, который создаёт форму приложения:
Код:
       //отправитель сигнала
       ThreadCore sender = (ThreadCore)signalSender();
       wv = new QWebView();
       wv.load(new QUrl("http://site.com/")); /* на этом этапе всё равно
            ошибка "Cannot create children for a parent that is in a different thread.",
            несмотря на то, что QWebView и QUrl созданы в классе формы, т.е. главном потоке*/
       sender.setData(true);

« Последнее редактирование: Декабрь 03, 2009, 18:28 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
niXman
Гость
« Ответ #25 : Декабрь 03, 2009, 18:12 »

Цитировать
Всё так, но в методе(слоте) главного потока, который создаёт qwebview
а ты его вызываешь посредством сигнала, или как простой метод?
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #26 : Декабрь 03, 2009, 18:27 »

Сделал по аналогии с предложенным вариантом, т.е. вызывается этот слот сигналом потока, которому нужен qwebview. А этот слот делает qwebview, load(), берёт сендера и шлёт ему с помощью setData() результат о том, что загрузка страницы прошла нормально. В сендере есть другой сигнал который испускается при вызове setData(). Всё как было предложено вобщем.
Записан

kubuntu/Win7/x64/NetBeans
niXman
Гость
« Ответ #27 : Декабрь 03, 2009, 18:39 »

Окончательно запутался.
Структура приложения такая?


Из рабочих потоков, шлется сигнал на создание ВебВью? И рабочий поток должен получить обратно только-что созданный ВебВью?
« Последнее редактирование: Декабрь 03, 2009, 18:44 от niXman » Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #28 : Декабрь 03, 2009, 18:42 »

Spectre всё нормально описал вроде бы...
Нарисую - выложу) Продумаю вот только чтоб по-понятнее было.
« Последнее редактирование: Декабрь 03, 2009, 18:44 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
niXman
Гость
« Ответ #29 : Декабрь 03, 2009, 18:49 »

Цитировать
Spectre всё нормально описал вроде бы...
Тут столько всего понаписывали, что хер поймешь что из этого ТС предпочел.
Если структура приложения такая, и ответ на мой вопрос == ДА. То это реализуется за несколько минут(на с++. про яву хз). И на* вы столько понаписывали - хз. Наверное от скуки.
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


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