0x1337
0x1337

Reputation: 1104

Qt Cannot send events to objects owned by a different thread

I have mainwindow class with such slots in it:

void MainWindow::connect_to_server(const std::string& nickname,
                                   const std::string& ip, 
                                   int port)
{

    remote_server = new Server(nickname, ip, port);

    connect(remote_server, SIGNAL(error()), SLOT(connection_failed()));

    auto thread = new QThread(this);
    remote_server->moveToThread(thread);

    connect(thread, SIGNAL(started()), remote_server, SLOT(establish_connection()));
    connect(remote_server, SIGNAL(stop_thread()), thread, SLOT(quit()));

    thread->start();
}

void MainWindow::action_disconnect_triggered() {
    if (remote_server == nullptr) {
        return;
    }
    remote_server->disconnect();
    remote_server = nullptr;
}

And Server class:

void Server::establish_connection() {
    master_socket = std::move(
                std::unique_ptr<QTcpSocket>(new QTcpSocket(nullptr))
                );

    master_socket->connectToHost(ip.c_str(), port);
    master_socket->waitForConnected(timeout*1000);

    if (master_socket->state() == QAbstractSocket::UnconnectedState) {
        disconnect();
        emit error();
    }

    emit stop_thread();
}

void Server::disconnect() {
    if (master_socket) {
        master_socket->disconnectFromHost();
    }
}

Initially, I invoke MainWindow::connect_to_server where client successfully connected to remote server. Then, I invoke MainWindow::action_disconnect_triggered and on this stage I get such error:

enter image description here

Btw, when I run it in OS X 10.11, error does not emerge and all works properly. What am I doing wrong and how can I fix it?

Upvotes: 0

Views: 3414

Answers (2)

Rafael Fontes
Rafael Fontes

Reputation: 1353

You are connecting the objects before moving to thread. That way Qt cant find it in the new one. Just move to thrrqd before everything and this should work.

Upvotes: 0

Zaiborg
Zaiborg

Reputation: 2522

remote_server->disconnect(); might be the issue here.

you do not send the event directly, but you call the function and it gets invoked in your main thread.

try QMetaObject::invokeMethod(remote_server, "disconnect", Qt::QueuedConnection); to see if this problem still exists

cheers

Upvotes: 3

Related Questions