Connect one slot to multiple socket's readyRead() signal



  • I need to manipulate sockets connected to three servers and coordinate the sequence to read them. For convenience, I connect the three socket's readyRead() signal to just one slot "on_ready_read()", and distinguish them using

    socket = qobject_cast<QTcpSocket *>(QObject::sender());
    

    Then,

    if (socket == s1)
    {
         // read data, and show them in certain widgets, and do some thing, send data to socket if needed
         qDebug() << "s1";
    }
    else if (socket == s2)
    {
         // read data, and show them in certain widgets, and do some thing, send data to socket if needed
         qDebug() << "s2";
    }
    else if (socket == s3)
    {
        // read data, and show them in certain widgets, and do some thing, send data to socket if needed
    
        if (some_condition)
        {
              QMessageBox::critical();
        }
       
        qDebug() << "s3";
    }
    

    I noticed that when the message box is shown, "s3" stopped showing, but "s1" and "s2" are showing without blocked. I'm a little confused about this. You know, QMessageBox::xxxx() is blocking function, so "s3" won't show. But why "s2" and "s1" keep showing? Which thread my "on_ready_read()" slot is running in?


  • Lifetime Qt Champion

    Hi,

    That's because QMessabeBox::critical executes a local event loop.

    You could use QSignalMapper.



  • @SGaist thanks. Yes, i can understand that read of s3 is blocked. But not very clear about why s1 and s2 keep read. You know, there is only one slot function. Are they running in different threads now? Can you explain more?


  • Lifetime Qt Champion

    No but you still have an event loop running thus there still event processing going on.



  • @SGaist OK, I've understand that QMessageBox::xxxx executes a local event loop, so 's1' and 's2' can still read data.

    About using 'QSignalMapper'. I think all my code will execute in just on thread, the "GUI thread", right? So, the socket read event will be queued in the event loop. Even I use QSinalMapper, the all read event will come in sequential. So it is safe to just use one slot to handle them, am I right?


  • Lifetime Qt Champion

    What exactly are you trying to achieve ?



  • @SGaist The server data is not sent randomly. They have some sequence, such as, s1, s3, s2,...., so I need maintain a state machine on my side. I should parse the data read from them to decide which is the next socket to read from. So, split the 'read' operation in several 'slot's may make it more complicated. I think if I use just one 'slot', I can use 'goto' to jump around. Though it may be a little 'ugly'. Any good suggestions?



  • @diverger said in Connect one slot to multiple socket's readyRead() signal:

    'goto' to jump around

    I died a bit inside.

    I strongly suggest rethinking your design.

    if you want to stop processing signals from other sockets while the messagebox is displayed just add

    QSignalBlocker blockS1(s1);
    QSignalBlocker blockS2(s2);
    

    just before the call to QMessageBox::critical


Log in to reply
 

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