В моем приложении возникло странное поведение, когда я использую QtNetwork. Я могу легко создать экземпляры QTcpSever
и QTcpSocket
, и все работает нормально, но когда дело доходит до QTcpSocket::write()
, возникает следующая ошибка:
Ошибка
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is QThread(0x7f66a0020be0), current thread is QThread(0x7f66a0020e20)
QSocketNotifier: Can only be used with threads started with QThread
Что мне странно: я понятия не имею, что/где это QThread(0x7f66a0020e20)
и как на него повлиять (посмотрите отладку ниже)
Программа
Я расширяю свое основное приложение (библиотеку) поддержкой сети. Я помещаю сетевые службы в дополнительный класс.
вот выдержка из основного приложения/библиотеки, где создается моя сетевая поддержка:
QThread *thread = new QThread;
wifi = new WirelessNet(0, thread);
wifi->moveToThread(thread);
connect(thread,SIGNAL(started()), wifi,SLOT(initWifi()));
thread->start();
расширение сетевого класса:
WirelessNet::WirelessNet(QObject *parent, QThread *comThread): QTcpServer(parent)
{
clientThread = comThread;
}
void WirelessNet::initWifi()
{
listen(QHostAddress::Any, 5220);
connect(this,SIGNAL(newConnection()),this,SLOT(connectionRequest()));
}
void WirelessNet::connectionRequest()
{
client = this->nextPendingConnection();
if(client)
connect(client, SIGNAL(readyRead()), this, SLOT(receiveMessage()));
}
void WirelessNet:sendData(QByteArray msg)
{
if (client)
{
qDebug()<<"FIRST "<< client->thread() << " - " << this->thread() << "\n";
client->write(msg);
client->waitForBytesWritten();
qDebug()<<"LAST " << client->thread() << " - " << this->thread() << "\n";
}
}
(client и clientThread являются членами класса: QTcpSocket*, QThread* соответственно)
Отладка
Вот что выводит консоль, когда дело доходит до части sendData()
:
FIRST QThread(0x7f66a0020be0) - QThread(0x7f66a0020be0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is QThread(0x7f66a0020be0), current thread is QThread(0x7f66a0020e20)
QSocketNotifier: Can only be used with threads started with QThread
LAST QThread(0x7f66a0020be0) - QThread(0x7f66a0020be0)
Заключение
Другими словами, я понятия не имею, к какому объекту я должен применить moveToThread()
. Я уже пробовал client->moveToThread(clientThread)
, а также this->moveToThread(clientThread)
. К сожалению, я не вижу дополнительных объектов для проверки.
У кого-нибудь есть идея?
clientThread = comThread;
, но затем, когда вы создаете WirelessNet, вы передаете 0 для родителя, что хорошо, но вы не передаете второй аргумент для потока...:wifi= new WirelessNet(0);
. Зачем вам нужно проходить в потоке? - вы можете просто создать его по мере необходимости в WirelessNet (возможно, иметь его как переменную-член), например.QThread *m_ClientThread
, а затемm_ClientThread = new QThread;
Теперь у вас есть новый поток, и все он инкапсулирован в WirelessNet (и вы можете использовать moveToThread...). - person code_fodder   schedule 31.03.2016moveToThread()
в требуемый родительский поток. Дело в том, что все (я знаю) уже настроено на родительский поток, но этот неясный объект, который я ищу - я надеялся, что это стало ясно из части сообщения отладка. - person user3085931   schedule 31.03.2016WirelessNet:sendData
непосредственно из основного потока, не так ли? - person thuga   schedule 31.03.2016main.cpp
) тестовый пример. См., например. этот ответ для примера того, как должен выглядеть код в вашем вопросе. - person Kuba hasn't forgotten Monica   schedule 31.03.2016QThread::currentThread()
- возвращаетQThread *
, но что вы делаете с этим указателем QThread? - почему-то мне кажется, что что-то еще может быть не так :o - person code_fodder   schedule 31.03.2016QThread *
только для отладки, поэтому я не смешиваю потоки, как хотел Qt. Я уже удалил их снова. - person user3085931   schedule 31.03.2016