Legal way for blocking signals and slots and passing by reference



  • I currently have a main window class containing a tcp socket subclass and a socket thread (does all of the ready read parsing) that uses moveToThread. My issue is that I would like to get the information of the connected client (if connected) on closeEvent in the main window and store it to an ini file.

    For example:
    @
    // create the data socket
    // this is a subclass of a QTcpSocket
    // all socket communications will be done within a thread
    _socket = new DataSocket();
    _socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
    qRegisterMetaTypeQAbstractSocket::SocketState("QAbstractSocket::SocketState");
    connect(_socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
    this, SLOT(connectionStateChanged(QAbstractSocket::SocketState)));
    connect(_socket, SIGNAL(error(QString)), this, SLOT(error(QString)));
    connect(this, SIGNAL(connectToServer(QString,uint)), _socket, SLOT(connectToServer(QString,uint)));
    connect(this, SIGNAL(disconnectFromServer()), _socket, SLOT(disconnectFromServer()));

    _socketThread = new QThread(this);
    _socket->moveToThread(_socketThread);
    _socketThread->start();
    @

    I do not believe it is legal to simply do this in the close event since the object is in another thread:
    @
    // close event
    void MasterView::closeEvent(QCloseEvent *){
    // save all settings
    saveSettings();

    // kill the socket thread if it is still running
    if (_socketThread->isRunning()){
        _socketThread->quit();
    }
    

    }

    // save all settings
    void MasterView::saveSettings(){
    // save the last ip address
    if (_socketState == QAbstractSocket::ConnectedState){
    _settingsIni->write("Connection", "LastIP", _socket->peerAddress().toString());
    _settingsIni->write("Connection", "LastPort", QString::number(_socket->peerPort()));
    } else {
    // clear the connection information
    _settingsIni->removeKey("Connection", "LastIP");
    _settingsIni->removeKey("Connection", "LastPort");
    }
    }
    @

    Getting the socket state is simple enough by just hooking up the connection state change event to the main window and just saving the state as it changes (in the example, that would be stored in _socketState).

    The only two lines I don't think are valid are the ones getting the peer address and peer port due to the _socket object living in another thread from the moveToThread...
    @
    _settingsIni->write("Connection", "LastIP", QVariant(_socket->peerAddress()));
    _settingsIni->write("Connection", "LastPort", QVariant(_socket->peerPort()));
    @

    The only other way I can think of getting this information is creating a blocking signal/slot for the main window to the socket thread that passes a QString (ip address) by reference and an unsigned int (port) by reference to the thread, and just filling the objects from the socket thread.

    For example:
    @
    connect(this, SIGNAL(peerInformation(QString&,uint&)), _socket, SLOT(peerInformation(QString&,uint&)), Qt::BlockingQueuedConnection);
    @

    I have never really ever needed a blocking signal / slot before between threads, so I am curious what the best way to do this would be, or if there is a better way to gather this information with out using global data? Or am I thinking about this all wrong?

    Edt: This is the way I have tried, and seems to work okay
    @
    // save the last ip address
    if (_socketState == QAbstractSocket::ConnectedState){
    QString ipAddress;
    unsigned int portNumber;
    QMetaObject::invokeMethod(_socket, "peerInformation", Qt::BlockingQueuedConnection,
    Q_ARG(QString&, ipAddress), Q_ARG(unsigned int&, portNumber));
    _settingsIni->write("Connection", "LastIP", ipAddress);
    _settingsIni->write("Connection", "LastPort", QString::number(portNumber));
    } else {
    // clear the connection information
    _settingsIni->removeKey("Connection", "LastIP");
    _settingsIni->removeKey("Connection", "LastPort");
    }
    @


  • Moderators

    Hi,

    I'd say that your use of invokeMethod() is already the best way to handle this.


Log in to reply
 

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