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. How do I send text from one thread to main GUI?

How do I send text from one thread to main GUI?

Scheduled Pinned Locked Moved Solved General and Desktop
messagesthreadssignal&slot
5 Posts 3 Posters 3.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.
  • R Offline
    R Offline
    rjmoses
    wrote on last edited by rjmoses
    #1

    I might have party too hard over the weekend, but this problem has me stymied.

    I am working on an application that is structured similarly to the QT examples threadedfortuneserver and fortuneclient, so I am going to use them as my working example.

    The question in its simplest form is how do I modify a QLabel text in the main thread from another thread which does not know about the GUI?

    Specifically, this question can be demonstrated by wanting to send a QString

    QString connectionMsg = "Remote connection received from: " + tcpSocket.peerAddress().toString();
    

    from fortunethread.cpp to the main dialog window to modify the text of statusLabel in dialog.cpp?

    In the sample program, fortunethread.cpp has no way of knowing anything about dialog and, as implemented in the example, cannot be modified to use signals/slots since there is no way to connect them (at least as far as I can find.)

    Any thoughts will be greatly appreciated.

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2
      • add a signal to FortuneThread
      • add the same signal to FortuneServer
      • add a slot to Dialog
      • emit signal in FortuneThread
      • connect FortuneThread's signal to FortuneServer signal in FortuneServer
      • connect FortuneServer's signal to Dialog's slot in the dialog

      done, should work :-)

      (Z(:^

      1 Reply Last reply
      8
      • R Offline
        R Offline
        rjmoses
        wrote on last edited by
        #3

        I think I followed the outline as you suggested. I get the execution time message "QObject::connect: No such signal FortuneThread::connectionMade(QString msg) in ../threadedfortuneserver/fortuneserver.cpp:78"

        I used this example program with changes as follows:

        Added to dialog.h:
        public slots:
        void setConnectionText (QString msg );

        Added to dialog.cpp
        void Dialog::setConnectionText(QString msg) {
        statusLabel->setText(msg);
        }

        Added to fortuneserver.h
        signals:
        void connectionMade(QString msg);

        Added to fortuneserver.cpp FortuneServer::incomingConnection
        connect(thread, SIGNAL(connectionMade(QString msg)), this, SIGNAL(connectionMade(QString msg)));

        Added to fortunethread.h
        void connectionMade(QString msg);

        Added to fortunethread.cpp in FortuneThread::run():
        QString connectionMsg = "Remote connection from: " + tcpSocket.peerAddress().toString();
        emit connectionMade(connectionMsg);

        Had you tested your response? Did I miss something from your outline?

        I'm confused by the connecting SIGNAL to SIGNAL--This seems like a very indirect way of connecting different classes. How does it work internally?

        Thanks

        1 Reply Last reply
        1
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          Hi
          Signal to signal is ok. it simply forwards a signal.

          It's not so odd as it seems. Default the UI part of a form/widget is private. if you want to let the outside world connect to any widget in the UI struct, then a clean way is simply to expose the signal in question via signal to signal connects internally. So outside world connects to a "repeated" signal and knows little about the actual widget. This is a decoupling design and very beneficial with apps that have long lifespans as they are more resilient to change.

          However, a small error in the connect.
          You included the parameter name also. should just be the type
          connect(thread, SIGNAL(connectionMade(QString msg)), this, SIGNAL(connectionMade(QString msg)));
          ---> change to
          connect(thread, SIGNAL(connectionMade(QString )), this, SIGNAL(connectionMade(QString )));

          and preferably check the return type
          like
          if (! connect(thread, SIGNAL(connectionMade(QString )), this, SIGNAL(connectionMade(QString ))) ) {
          qDebug() << "connect fail";
          }
          or use the (not so) new compile time checking syntax
          https://wiki.qt.io/New_Signal_Slot_Syntax

          R 1 Reply Last reply
          7
          • mrjjM mrjj

            Hi
            Signal to signal is ok. it simply forwards a signal.

            It's not so odd as it seems. Default the UI part of a form/widget is private. if you want to let the outside world connect to any widget in the UI struct, then a clean way is simply to expose the signal in question via signal to signal connects internally. So outside world connects to a "repeated" signal and knows little about the actual widget. This is a decoupling design and very beneficial with apps that have long lifespans as they are more resilient to change.

            However, a small error in the connect.
            You included the parameter name also. should just be the type
            connect(thread, SIGNAL(connectionMade(QString msg)), this, SIGNAL(connectionMade(QString msg)));
            ---> change to
            connect(thread, SIGNAL(connectionMade(QString )), this, SIGNAL(connectionMade(QString )));

            and preferably check the return type
            like
            if (! connect(thread, SIGNAL(connectionMade(QString )), this, SIGNAL(connectionMade(QString ))) ) {
            qDebug() << "connect fail";
            }
            or use the (not so) new compile time checking syntax
            https://wiki.qt.io/New_Signal_Slot_Syntax

            R Offline
            R Offline
            rjmoses
            wrote on last edited by
            #5

            @mrjj

            Thank you, thank you, thank you. It is always a pleasure to work with someone who knows their stuff.

            I had overlooked the step of connecting FortuneServer's signal to Dialog's slot in the dialog.

            I added in dialog.cpp:
            connect(&server, SIGNAL(connectionMade(QString)), this, SLOT(setConnectionText(QString)) );

            Once I put this in, it worked like a champ!

            Marking it solved.
            Thanks again.

            1 Reply Last reply
            3

            • Login

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