Russian Qt Forum

Qt => Работа с сетью => Тема начата: 0xFF от Июнь 28, 2010, 21:25



Название: QThread, QTcpSocket
Отправлено: 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&)));

Собственно интересует из-за чего такое происходит, и правильно ли я юзаю поток.


Название: Re: QThread, QTcpSocket
Отправлено: navrocky от Июнь 28, 2010, 21:33
Сокет тоже надо move to thread


Название: Re: QThread, QTcpSocket
Отправлено: 0xFF от Июнь 28, 2010, 22:04
Он же в run'e создается, хотя один черт socket->moveToThread(this) не помогает.


Название: Re: QThread, QTcpSocket
Отправлено: Vass от Июнь 28, 2010, 23:49
Как я понял вы из треда ГУЯ трогаете методы сокета, который живет в другом треде, вот он и ругается, сигналы надо посылать вместо вызовов, при вызове вы выполняете метод сокета в треде ГУЯ.
Поэтому вариант получается примерно такой, наследуютесь от сокета, добавляете слотов оберток (посмотрел щас асситант удивился, что у сокета слотов вообще нету) на рид/райт, в треде создаете объект уже от вашего гласса сокета, в ГУИ треде объявляете сигнала сокетРид/сокетРайт, конектите их к слотам вашего сокета.

Как-то так.


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


Название: Re: QThread, QTcpSocket
Отправлено: 0xFF от Июнь 29, 2010, 06:48
Вроде переписал, работает, и даже каши нет)
Спасибо за помощь.


Название: Re: QThread, QTcpSocket
Отправлено: SimpleSunny от Июнь 29, 2010, 09:17
Вместо сигналов можно попробовать использовать invokeMethod с параметром  Qt::QueuedConnection.