Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Can't receive tcp message when popping up a modal dialog?
QtWS25 Last Chance

Can't receive tcp message when popping up a modal dialog?

Scheduled Pinned Locked Moved General and Desktop
11 Posts 6 Posters 9.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    javid
    wrote on last edited by
    #1

    My goal is to receive the tcp message from the server, and execute some jobs.
    But it's hard to copy all code to here...

    In short, I refer to the Qt example "Fortune client", make it connect to server, receive message, etc.
    Just like the example :

    @
    connect(tcpSocket, SIGNAL(readyRead() ), this, SLOT(slot_myReadMsg()) );
    @

    And the slot_myReadMsg() :

    @
    void QxSpySocket::slot_myReadMsg(){
    QDataStream in(connection);
    in.setVersion(QDataStream::Qt_4_0);
    if (blockSize == 0) {
    if (connection->bytesAvailable() < (int)sizeof(quint16))
    return;
    in >> blockSize;
    }
    if (connection->bytesAvailable() < blockSize)
    return;
    QString msg;
    in >> msg;
    blockSize = 0;
    QxSpy::getInstance()->slot_parseTCPMessage(msg);
    }
    @

    It works fine for a while.
    But recently, I found a weird problem of Qt.

    When I open a modal dialog, then the server sends message to client, readyRead() never be triggered.
    Why? Does it mean that when I open a modal dialog, qt will be blocked at the dialog until I click "OK" or "Cancel"?

    After that I've tried to create two socket, one for write, one for read.
    Make one of them to listen in another thread (see Example "Blocking Fortune Client")
    The thread just like this :

    @
    void QxSocketThread::run(){
    const int Timeout = 60 * 1000;

    while(1){
    QString command = "";
    while (_socket->getSocket()->bytesAvailable() < (int)sizeof(quint16)) {
    if (!_socket->getSocket()->waitForReadyRead(Timeout)) {
    //emit error(_socket->getSocket()->error(), _socket->getSocket()->errorString());
    return;
    }
    }
    quint16 blockSize;
    QDataStream in(_socket->getSocket());
    in.setVersion(QDataStream::Qt_4_0);
    in >> blockSize;

    while (_socket->getSocket()->bytesAvailable() < blockSize) {
    if (!_socket->getSocket()->waitForReadyRead(Timeout)) {
    //emit error(_socket->getSocket()->error(), _socket->getSocket()->errorString());
    return;
    }
    }
    in >> command;

    MyCommandParser::getInstance()->parse(command);
    msleep(50);
    }
    }
    @

    In VC, it will output the warning : "QSocketNotifier: socket notifiers cannot be disabled from another thread"
    I've read several thread about it, but none of them can tackle it.

    Anyone can help me??? Plz...
    My opinion, I like the signal-slot approach rather than the blocking approach.

    1 Reply Last reply
    0
    • G Offline
      G Offline
      goetz
      wrote on last edited by
      #2

      While a message box is open with exec, it will run its own event loop. During this time, the main event loop is not run and therefore the events and signals are not processed.

      http://www.catb.org/~esr/faqs/smart-questions.html

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dangelog
        wrote on last edited by
        #3

        bq. When I open a modal dialog, then the server sends message to client, readyRead() never be triggered.
        Why? Does it mean that when I open a modal dialog, qt will be blocked at the dialog until I click “OK” or “Cancel”?

        No: opening a dialog with exec() will reenter the event loop (with all the pros/cons).

        http://developer.qt.nokia.com/wiki/Threads_Events_QObjects

        Software Engineer
        KDAB (UK) Ltd., a KDAB Group company

        1 Reply Last reply
        0
        • J Offline
          J Offline
          javid
          wrote on last edited by
          #4

          Thanks to Volker and peppe.

          So, does it means I never could open a dialog with exec() and listen the socket message??
          is there any possible implementation?

          It's a classical web client program. User can manipulate and the program will communicate with server in background.
          But I just open a modal dialog (QFileDialog) to ask user to select a file :

          @
          QString fileName = QFileDialog::getOpenFileName(label, "Open Image",
          "C:\", "Image Files (*.png *.xpm *.jpg)");

          if(fileName != NULL) {
          label->setText("<center>" + fileName + "</center>");
          }
          @

          Does it means that the modal window is a bad use?

          thanks again.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            Arguably, most model dialogs are a design problem from a UI point of view to begin with, so in that sense the answer to your last question is "yes".

            You can open a modal dialog and still let the eventloop continue. Read up on the documentation of QDialog for tips on that. However, that will mean re-thinking your application flow, because the call to show the dialog will return immediately. The problem is, that especially for file dialogs on windows, you really want to use the static methods like you do in order to get the native file dialogs. And those are blocking by design. A bit of a catch 22, I'm afraid.

            One way out could be - dare I say it? - multithreading. If you put your networking code in a thread of its own, you can have your UI code show all the modal, blocking dialogs you want and still not stop the networking thread. However, threading brings its own set of problems and can get you into trouble real fast if you're not careful what you're doing.

            1 Reply Last reply
            0
            • J Offline
              J Offline
              javid
              wrote on last edited by
              #6

              Thank you Andre.

              I've tried to use multithread to tackle it before. But, as I say, When I put a socket to a thread , and make it continuously listen the tcp message, qt still shows the warning, "QSocketNotifier: socket notifiers cannot be disabled from another thread".

              Here's the code snippet :
              @
              void QxSocketThread::run(){
              const int Timeout = 60 * 1000;

              while(1){
              QString command = "";
              while (_socket->getSocket()->bytesAvailable() < (int)sizeof(quint16)) {
              if (!_socket->getSocket()->waitForReadyRead(Timeout)) {
              //emit error(_socket->getSocket()->error(), _socket->getSocket()->errorString());
              return;
              }
              }
              quint16 blockSize;
              QDataStream in(_socket->getSocket());
              in.setVersion(QDataStream::Qt_4_0);
              in >> blockSize;

              while (_socket->getSocket()->bytesAvailable() < blockSize) {
              if (!_socket->getSocket()->waitForReadyRead(Timeout)) {
              //emit error(_socket->getSocket()->error(), _socket->getSocket()->errorString());
              return;
              }
              }
              in >> command;

              MyCommandParser::getInstance()->parse(command);
              msleep(50);
              }
              }
              @
              When the socket is connected (signaled in main thread), I put it t to another thread, and start it.
              Does anybody meet this problem?

              One more question, follow this flow :

              1. main thread : open a modal dialog (execute it in a slot function).
              2. my thread : receive tcp message, and try to update ui, emit a signal to ui object.
              3. main thread : close the modal dialog.
              4. Does the ui will be updated?

              I just wondering whether signal-slot is asynchronous or not?
              At step 1, this slot is blocking be the "dialog.exec()",
              At step 2, there's another signal be emitted.
              Will qt handle this signal immediately? or it will hand this signal after the modal dialog be closed?

              thank you all guys again.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                Ehm... yes. Well, it seems that You Are Doing It Wrong (TM).

                The (now) recommended way to use threading, is to use QThread as-is. Don't subclass it, but instead push a parent-less, QObject-derived worker object to the newly created thread to make it do its work in that thread.

                This wiki article gives an overview of your options and pitfalls: http://developer.qt.nokia.com/wiki/Threads_Events_QObjects

                Edit:

                On your last question:

                Signal-slot can be asynchronous. There are basically three connection modes:

                • a direct connection: this is a synchronous connection. Connected slots are executed immediately.
                • an queued connection: this is an asynchronous connection. Signals are marchalled as an event on the event loop of the receiving object, and executed when that event is processed by that event loop. The caller will continue executing immediately.
                • a blocking queued connection: same as the above, but execution of the calling code halts until all connected slots have finished executing.

                The standard connection type is autoConnection. This type works as a direct connection in the normal, non-threaded case. When a signal crosses a thread-boundary (that is, the thread affinity of the sending object and of the receiving object are not the same), auto connection uses a queued connection.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  arianoo
                  wrote on last edited by
                  #8

                  if u create the my thread(tcp thread) inside your main thread and run it from that thread not other classes and if u also connect the signals and slots in your main thread and manage all events in that i think ur problem will be solved.
                  u should pay attention to start the tcp thread from ur main thread and no where else and to create it there and add this class to the header of your main thread
                  i think if u do this exactly your program will work correclty

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    Eh? Why are you necroposting? This topic has been dead for about eight months. I guess if the poster still had a problem, he would have replied by now...

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lgeyer
                      wrote on last edited by
                      #10

                      I guess you've meant necroposting ;-)

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        [quote author="Lukas Geyer" date="1319212513"]I guess you've meant necroposting ;-)[/quote]
                        Shame
                        Yes, I totally meant that. I have corrected the offending posting, and apologize if anyone was offended by it.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved