Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法使用QtNetwork,因为应用程序使用不同的线程_C++_Qt_Qthread_Qobject_Qtnetwork - Fatal编程技术网

C++ 无法使用QtNetwork,因为应用程序使用不同的线程

C++ 无法使用QtNetwork,因为应用程序使用不同的线程,c++,qt,qthread,qobject,qtnetwork,C++,Qt,Qthread,Qobject,Qtnetwork,当我使用QtNetwork时,我的应用程序中出现了一个奇怪的行为。我可以轻松创建qtcsocket和qtcsocket实例,一切运行正常,但是当涉及qtcsocket::write()时,会出现以下错误: 错误 QObject: Cannot create children for a parent that is in a different thread. (Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is Q

当我使用QtNetwork时,我的应用程序中出现了一个奇怪的行为。我可以轻松创建
qtcsocket
qtcsocket
实例,一切运行正常,但是当涉及
qtcsocket::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";
}
}
总结

换句话说,我不知道应该在哪个对象上应用
moveToThread()
。我已经尝试了
client->moveToThread(clientThread)
以及
this->moveToThread(clientThread)
。不幸的是,我没有看到任何其他要检查的对象


有人知道吗?

我猜类的构造函数在调用线程中被调用,而线程本身在类的
run()
方法中运行。解决方案是在
run()
方法开始时初始化
qtcserver
,这样初始化和通过该类的通信就在同一个线程中完成。

您似乎是直接从主线程调用
WirelessNet:sendData
。这会导致该函数中的所有内容也在主线程中运行。您的
客户端
位于新线程中,它不是线程安全的。它试图创建子线程,但当前线程与
client
所在的线程不同。这就是为什么您会收到错误消息


您只需将
WirelessNet:sendData
设置为一个插槽,并通过主线程的信号调用即可解决此问题。

我不明白clientThread是如何/在何处设置的。在构造函数
clientThread=comThread,但当您创建WirelessNet时,您为父级传入0,这很好,但您没有为线程传递第二个参数…:<代码>wifi=新无线网络(0)。为什么你需要传递一个线程您可以根据需要在WirelessNet中创建一个(可能将其作为成员变量),例如
QThread*m_ClientThread
,然后
m_ClientThread=new QThread
然后你的新线程和它的所有内容都封装在WirelessNet中(你可以使用moveToThread…。@code\u fodder对不起,这是一个打字错误。我更新了最上面的帖子(主应用程序)。我传递线程,以便
移动到线程()
到所需的父线程。问题是,所有(我知道)的内容都已经设置为父线程,但我正在寻找的模糊对象-我希望在文章的调试部分可以清楚地看到。你不会碰巧直接从主线程调用
WirelessNet:sendData
,是吗?这个问题没有包含足够的代码来重现问题,因此,这是离题的。将来,当提出此类问题时,请创建一个最小的、自包含的(单个
main.cpp
)测试用例。例如,请参阅问题中代码的外观示例。这不是问题所在,正如thuga指出并回答的那样,您从另一个线程+1调用了函数方向,但只是想澄清另一件事。您将线程指针传递到移动到的线程的WirelessNet,并将其存储在clientThread中。您不需要这样做,您可以使用
QThread::currentThread()
-返回
QThread*
,访问当前线程,但是您使用这个QThread指针做什么呢?-不知怎的,它给了我一种感觉:我尝试了一个额外的
qtcserver*
成员,在
initWifi()
中初始化,并移动到
clientThread
,为这个成员服务器设置的一切,扩展了qDebug()使用该服务器线程(现在与其他所有线程相同),但错误是一致的,您可以在执行代码的位置使用
QThread::currentThread()
进行检查。我认为,
initWifi
也是由原始线程调用的。我真的想把它放在你的
运行方法的开始部分,我不确定你想的是哪个
run()
。类
WirelessNet
继承自
qtcserver
,我没有实现
run()
,也没有执行
wifi->start()
。但是,由于第一次调用initWifi,当wifi已经移动到新线程时,就我所知,不应该再在旧线程中创建任何内容,忘记
run
。但是,您是否检查了调用哪个线程
initWifi
?你是对的,它以前已经移动到了新线程,但是某种线程不匹配似乎持续存在。感谢你的帮助,因为thuga指出我错过了发送的信号/插槽通信,我是直接从main调用此函数的。它正在工作
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)