1

我在 MyThread.cpp 和 .h 中定义了一个 QThread。那里我有一个私人 QTcpSocket。

class MyThread: public QThread {

    Q_OBJECT

public:
    MyThread();
    virtual ~MyThread();

public slots:
    void reconnect();
signals:

protected:
    void run(void);

private:
    QTcpSocket *socket;
};

void MyThread::run(void) {
    bool connected = false;

    connected = prepareSocket(QString::fromLatin1((Global::directionIPSerialServer).toLocal8Bit().data()), 8008, socket);
}

另一方面,我在 Functions.cpp 和 .h 中定义了一组函数,它们没有定义在 Functions 类中,而是定义在命名空间中。

bool Functions::prepareSocket(QString address, int port, QTcpSocket *socket) {
    socket->connectToHost(address, port);
    if(!socket->waitForConnected(Global::maxTimueToConnectByTCP)){
        qDebug()<<"Error: "<<socket->errorString();
        return false;
    }
    return true;
}

然后,如果我错了,请纠正我,当我在 Functions 中调用一个函数以将 MyThread 的 QTcpSocket 连接到主机时,我假设我在同一个线程上,因为我正在从线程调用函数我已经创造,而不是一个不同的。

尽管如此,在 socket->connectToHost 上,我得到QObject: Cannot create children 为位于不同线程中的父级。两次。

这是为什么?怎么了?

4

2 回答 2

1

你不应该从 QThread 派生。在派生自 QObject 的类上实现所有内容。然后,您可以选择调用moveToThread()该 QObject 以将其移动到新线程。但是,您会发现,通常不需要将其移至新线程因为现在您将拥有不会停止 GUI 线程的异步、非阻塞代码。

他们这样做的关键是永远不要使用waitxxx电话。每当您想等待某件事时,您会发现当该事情发生(或失败)时会发出一个信号。将插槽连接到该信号。您可能需要多次执行此操作——不同的插槽用于不同的信号。这就是您正确编码异步、事件驱动的应用程序的方式。

只有在不存在其他 API 时才使用阻塞调用。众所周知,数据库驱动程序和名称解析器在这方面很糟糕,但它们是唯一的反例。让他们孤独地死去吧,我说。

于 2012-06-01T09:12:25.183 回答
1

尝试:QObject::moveToThread。这应该可以解决问题。

于 2012-05-03T11:39:02.023 回答