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;
}

次に、間違っている場合は修正します。関数を関数に呼び出してMyThreadのQTcpSocketをホストに接続すると、同じスレッドにいると思います。これは、自分が持っているスレッドから関数を呼び出しているためです。作成されたものであり、別のものではありません。

それにもかかわらず、socket-> connectToHostでQObjectを取得しています:別のスレッドにある親の子を作成できません。2回。

何故ですか?どうしたの?

4

2 に答える 2

1

試してください:QObject::moveToThread。これでうまくいくはずです。

于 2012-05-03T11:39:02.023 に答える
1

QThreadから派生するべきではありません。QObjectから派生したクラスにすべてを実装します。次に、オプションmoveToThread()でそのQObjectを呼び出して、新しいスレッドに移動できます。ただし、 GUIスレッドを停止させない非同期の非ブロッキングコードがあるため、通常は新しいスレッドに移動する必要はありません。

それを行うための鍵は、決してwaitxxx呼び出しを使用しないことです。何かを待ちたいときはいつでも、そのことが起こったとき(または失敗したとき)に発せられる信号があることに気付くでしょう。その信号にスロットを接続します。あなたはそれを複数回行う必要があるかもしれません-異なる信号のための異なるスロット。これが、非同期のイベント駆動型アプリケーションを正しくコーディングする方法です。

他のAPIが存在しない場合にのみ、ブロッキング呼び出しを使用します。データベースドライバと名前リゾルバはこの点で悪名高いことで有名ですが、それらは孤独な反例です。彼らを孤独に死なせてください、と私は言います。

于 2012-06-01T09:12:25.183 に答える