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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QThread, QTcpSocket  (Прочитано 8233 раз)
0xFF
Гость
« : Июнь 28, 2010, 21:25 »

Доброго времени суток.
Знаю, тема избитая, но что-то немогу найти решение.

Есть поток с сокетом, сокет создается в run'e
Код:
socket = new QTcpSocket();
connect(socket, SIGNAL(readyRead()), SLOT(readData()));
exec();
Сам поток создаю в конструкторе окна:
Код:
thread = new MyThread();
connect(thread, SIGNAL(connected(bool)), this, SLOT(createConnection(bool)));
thread->moveToThread(thread);
thread->start();
У класса потока(MyThread) есть метод sendData, примерно такой:
Код:
socket->write(data);
socket->flush();

Так вот, при вызове в методах окна socket->sendData(...) креатор бомбит в дебаге
Код:
QSocketNotifier: socket notifiers cannot be enabled from another thread
QSocketNotifier: socket notifiers cannot be disabled from another thread
При вызове других методов потока аналогичная ситуация, приводящая к вылету приложения.
Например метод Disconnect() { socket->abort(); } кидает
Код:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 3e4dc0. Receiver '' (of type 'QTcpSocket') was created in thread 63a7c30", file kernel\qcoreapplication.cpp, line 347
и завершает приложение.
Если вместо вызова метода напрямую использовать сигналы, то ошибки нет.
Код:
connect(this, SIGNAL(SEND(const QString&), thread, SLOT(sendData(const QString&)));

Собственно интересует из-за чего такое происходит, и правильно ли я юзаю поток.
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #1 : Июнь 28, 2010, 21:33 »

Сокет тоже надо move to thread
Записан

Гугль в помощь
0xFF
Гость
« Ответ #2 : Июнь 28, 2010, 22:04 »

Он же в run'e создается, хотя один черт socket->moveToThread(this) не помогает.
Записан
Vass
Гость
« Ответ #3 : Июнь 28, 2010, 23:49 »

Как я понял вы из треда ГУЯ трогаете методы сокета, который живет в другом треде, вот он и ругается, сигналы надо посылать вместо вызовов, при вызове вы выполняете метод сокета в треде ГУЯ.
Поэтому вариант получается примерно такой, наследуютесь от сокета, добавляете слотов оберток (посмотрел щас асситант удивился, что у сокета слотов вообще нету) на рид/райт, в треде создаете объект уже от вашего гласса сокета, в ГУИ треде объявляете сигнала сокетРид/сокетРайт, конектите их к слотам вашего сокета.

Как-то так.
Записан
0xFF
Гость
« Ответ #4 : Июнь 29, 2010, 05:41 »

Хм, а обязательно наследоваться от QTcpSocket? Что это даст в моем случае?
Как я уже писал
Код:
connect(this, SIGNAL(SEND(const QString&), thread, SLOT(sendData(const QString&)));
такая штука, по крайней мере для проблемного метода, работает, в sendData метод сокета, но я нехотел так делать, т.к. придется пихать в класс немало сигналов.
Сейчас попробую сделать через сигналы, лишь бы уже заработало.
Записан
0xFF
Гость
« Ответ #5 : Июнь 29, 2010, 06:48 »

Вроде переписал, работает, и даже каши нет)
Спасибо за помощь.
Записан
SimpleSunny
Гость
« Ответ #6 : Июнь 29, 2010, 09:17 »

Вместо сигналов можно попробовать использовать invokeMethod с параметром  Qt::QueuedConnection.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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