我遇到了一个问题,几次在这里问类似的情况,但是在这些主题中找不到解决方案。

我有一个主类,我想用一个qt-network支持来扩展它,并增加一个附加类。让我将源代码分解为相关部分:

主类

。H

class MainClass: public QObject{
    Q_OBJECT
public:
[...]
private:
    NetworkSupport * netSupport;
};

.cpp
MainClass::MainClass()
{
    [...]
    netSupport
    netSupport = new NetworkSupport(this->thread());
    netSupport->start();
    [...]
}

网络类

。H
class NetworkSupport : public QThread
{
    Q_OBJECT
public:
    NetworkSupport(QThread *mainThread);
    ~NetworkSupport();

    QByteArray readData();
    void sendData(QByteArray *msg);

public slots:
    void acceptConnection();
    void receive();
    void run();

private:
    QByteArray curMessage;
    QThread* libThread;
    QEventLoop initWlan;

protected:
    QTcpServer server;
    QTcpSocket* client;
};

.cpp
NetworkSupport::NetworkSupport(QThread* mainThread)
{
    libThread = mainThread;
    server.moveToThreaD(libThread);
    server.listen(QHostAddress::Any, 5200);

    QMetaObject::invokeMethode(&initWlan, "quit", Qt:QueuedConnection);
    initWlan.exec();
}

void NetworkSupport::run(){
    connect(&server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
}

void NetworkSupport::acceptConnection()
{
    client = server.nextPendingConnection();
    client->moveToThread(libThread);

    if (client->state() == QAbstractSocket::ConnectedState)
        connect(client, SIGNAL(readyRead()), this, SLOT(receive()));

}

void NetworkSupport::receive()
{
    curMessage = client->readAll();
}

void NetworkSupport::sendData(QByteArray* msg)
{
    if(client->state() == QAbstractSocket::ConnectedState)
    {
        client->moveToThread(libThread);
        printf("Sending a message %s\n",msg->data());
        client->write(*msg);
        client->waitForBytesWritten();
    }
}

我知道我通常不需要这么多指定moveToThread(),但是如果所有人都存在或删除,它最终都不会改变任何事情。

但是,执行时,我在client->write(*msg)sendData()处收到错误消息,即:
[...]
Sending a message ?r
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QnativeSocketEngine(0x2afc660), parent's thread is QThread(0x1b59210), current thread is QThread(0x7f6a70026b60)
QSocketNotifier: Can only be used with threads started with QThread
[...]

确实看起来像是警告,因为程序此后仍在执行中,但是我没有从客户端收到任何消息(即receive()从未执行过),这是因为错误消息的最后一行。

可能是此错误消息只是误导,如果是这样,它的实际含义是什么,还是我做的事情完全错误?

最佳答案

您在这段代码中做错了太多事情,因此我不确定该从什么开始。

NetworkSupport::NetworkSupport(QThread* mainThread)
{
    libThread = mainThread;
    server.moveToThreaD(libThread);

这将无济于事。 server与MainClass实例已经在同一线程中
    server.listen(QHostAddress::Any, 5200);

服务器将开始监听与MainClass相同的线程
    QMetaObject::invokeMethode(&initWlan, "quit", Qt:QueuedConnection);
    initWlan.exec();

这让我很恶心。这将简单地启动事件循环并几乎立即退出。
}

void NetworkSupport::run(){
    connect(&server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
}

这将简单地在新线程中运行,在connect语句之后立即调用connect并退出线程-您的线程将在connect之后不再运行。此外,插槽acceptConnection可能会在与MainClass相同的线程中调用。我想知道MainClass在何时何地创建的。

在我看来,您正在同时努力应对许多事情。您可能在某处读过,因此应该使用单独的线程进行网络通信,因此不会阻塞其他线程。首先尝试单线程方法。当您开始工作时,您应该考虑如何根据需要使用其他线程。

额外的问题:这段代码是否是某种可能根本没有Qt eventloop的应用程序插件?还是它是全栈Qt应用程序的一部分?

关于c++ - (QNativeSocketEngine)QObject : Cannot create children for a parent that is in a different thread,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36036960/

10-11 00:49