Qt send signal to different thread

Łukasz Przeniosło picture Łukasz Przeniosło · Apr 28, 2015 · Viewed 9.7k times · Source

I have searched SO for this question, but they were a bit different than mine. My problem is that I dont want to receive a signal from another thread, but I want to send one. Receiving works in my app, but when trying to send, I am getting error that I am trying to send to another thread... I dont know how to fix this. This is my situation: I have a Gui application. In MainWindow class I create a myThread object, that is inherited from Qthread. I then start the new thread. In MainWindow a signal exists and in myThread a slot exists (this code is run in main window). When I try to do:

connect(this, SIGNAL(disconnect(),
        connectionThread, SLOT(stop()));

stop() is a slot in connection thread and disconnect() is a signal from MainWindow. When the signal is emited, i get:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 128f8250. Receiver '' (of type 'QNativeSocketEngine') was created in thread 14bae218", file kernel\qcoreapplication.cpp, line 521
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.

Is there a way to overcome this? I need to be able to send and receive events through signals and slots to and from the thread I created. I Would really aprichiate all help!

PS: I tried directlinking.

connect(this, SIGNAL(disconnectFromOven()),
            connectionThread, SLOT(stop()), Qt::DirectConnection);

This is the code: MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void moveUndoView();

signals:
    void disconnectFromOven();

};

#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initComponents();

    QString ip = "10.10.10.17";
    int port = 5432;
    connectionThread = new TcpThread(ip, port, connectAndStay);

    show();

    // tcp connection
    connect(connectionThread, SIGNAL(connectionEstablished()),
            this, SLOT(on_connectionEstablished()));

    connect(connectionThread, SIGNAL(connectionNotEstablished()),
                this, SLOT(on_connectionNotEstablished()));

    connect(this, SIGNAL(disconnectFromOven()),
            connectionThread, SLOT(stop()));


}


void MainWindow::on_action_Disconnect_triggered()
{
    emit disconnectFromOven();
}

tcpthread.h:

#ifndef TCPTHREAD_H
#define TCPTHREAD_H

#include <QThread>
#include <QDebug>

#include "tcpconnection.h"

class TcpThread : public QThread
{
    Q_OBJECT
public:
    explicit TcpThread(QString& address,
                       int& port, conType_t conType, QObject *parent = 0);
    void run(); // inherited


signals:
    void connectionStatusOk();
    void connectionEstablished();
    void connectionNotEstablished();

private slots:
    void stop();
    void connectionClosed();
    void connectionOpened();
    void connectionOpenFailed();

};

#endif // TCPTHREAD_H

tcpthread.cpp:

#include "tcpthread.h"

TcpThread::TcpThread(QString& address,
                     int& port, conType_t conType, QObject *parent) :
    QThread(parent)
{
    this->address = address;
    this->port = port;
    this->conTypeRequested = conType;
}

void TcpThread::stop()
{
    qDebug() << "Thread stop called, requesting disconnect";
    tcpCon->doDisconnect();
}

Answer

Zlatomir picture Zlatomir · Apr 28, 2015

QThread (connectionThread) instance lives in the thread that instantiated it (main thread), not in the thread that calls run(), so if you want to call slots you need to use the first approach presented in the documentation here, look at the worker-object approach.