QTcpSocket used inside a thread: I can't get signal/slot working



  • Hi all,

    I'm struggling with QTcpSocket used inside a thread. I've already implemented successfully a Modbus client in QT. Now I'm trying to move this client inside a thread and I can't get it working using signal/slot mechanism.

    I instantiated my ModbusClient object inside the run method. QTcpSocket is created inside ModbusClient. After writing to the socket from requestHandler() method, receiveData() slot (connected with the readyRead() signal) is never called...

    mimicwindow.cpp:

    @
    mimicWindow::mimicWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::mimicWindow)
    {
    QTimer *timer;

    ui->setupUi(this);
    
    m_icon_ok = new QPixmap(":/images/ok.png");
    m_icon_not_ok = new QPixmap(":/images/not_ok.png");
    
    // Start modbus thread for reading data
    m_modbusHandler.start();
    // Update the mimic diagram every 500 ms
    timer = new QTimer(this);
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(updateMimicDiagram()));
    timer->start(500);
    
    QObject::connect(ui->pushButtonMimicHome, SIGNAL(released()), this, SLOT(goHome()));
    

    }
    @

    mimicwindow.h:

    @
    class mimicWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit mimicWindow(QWidget *parent = 0);
    ~mimicWindow();
    void centerWidgets();
    void showScreen();
    bool isMainsSupplyOk();
    bool isInverterOn();
    bool isRectifierOn();
    bool isInputCBOpen();
    bool isBatteryCBOpen();
    bool isOutputCBOpen();
    bool isBypassCBOpen();
    bool isBypassSSWOn();

    private:
    Ui::mimicWindow *ui;
    QPixmap *m_icon_ok;
    QPixmap *m_icon_not_ok;
    ModbusHandler m_modbusHandler;
    #define green ((QString)"{background-color: rgb(0,255,0);}")
    #define red ((QString)"{background-color: rgb(255,0,0);}")
    #define grey ((QString)"{background-color: rgb(221,221,221);}")
    typedef enum {
    BLOCK_ON = 0,
    BLOCK_OFF,
    BLOCK_FAULT
    } BLOCK_STATES;
    typedef struct {
    bool mainsInput;
    bool rectifierInput;
    bool rectifierOutput;
    bool inverterInput;
    bool inverterOutput;
    bool staticSwitchInput1;
    bool staticSwitchInput2;
    bool staticSwitchOutput1;
    bool staticSwitchOutput2;
    bool invSSWOutput;
    bool output1;
    bool output2;
    bool bypassInput1;
    bool bypassInput2;
    bool bypassOutput1;
    bool bypassOutput2;
    bool batteryOutput1;
    bool batteryOutput2;
    } LINES;
    typedef struct {
    bool inputCB;
    bool batteryCB;
    bool outputCB;
    bool bypassCB;
    } BREAKERS;
    typedef struct {
    BLOCK_STATES rectifier;
    BLOCK_STATES staticSwitch;
    BLOCK_STATES inverter;
    BLOCK_STATES battery;
    } BLOCKS;

    struct {
        LINES lines;
        BREAKERS breakers;
        BLOCKS blocks;
    } m_mimicDiagram;
    

    signals:
    void showMainScreen();

    public slots:
    void goHome();
    void updateMimicDiagram();
    };
    @

    modbushandler.cpp:

    @
    void ModbusHandler::run()
    {
    m_modbusClient = new ModbusClient("10.0.0.240", 502);
    m_modbusClient->openConnection();
    QObject::connect(m_modbusClient, SIGNAL(dataReceived()), this, SLOT(replyHandler()), Qt::QueuedConnection);

    forever {
        requestHandler();
        if (abort)
            return;
        msleep(50);
    }
    

    }
    @

    modbusclient.cpp:

    @
    ModbusClient::ModbusClient(QString ip_address, int port)
    {
    m_tcpSocket = new QTcpSocket();
    m_hostIpAddress = ip_address;
    m_modbusPort = port;
    m_queryTransactionId = 0;

    QObject::connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveData()), Qt::DirectConnection);
    QObject::connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this,
    SLOT(displayErrors(QAbstractSocket::SocketError)), Qt::DirectConnection);
    }
    @

    Could anyone help me?

    Maybe I'm just missing something basic...

    Thanks a lot in advance.



  • where the m_modbusHandler->run() is called? that's the function which connects signal with slot.



  • mohsen: run is the thread function that represents the thread. It is started, when m_modbusHandler.start(); is called.

    blueyes: are you sure the connects are correct (did you get debug messages that it's not)?

    Who is writing to the socket? (After writing to the socket from requestHandler() method)...

    Are you sure that the socket is correctly initialised?



  • Why are you using threads at all for sockets?
    Do you have an event loop in the ModbusHandler thread?
    Why are you adding slots to QThread subclasses?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.