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. QLabel won't update from Slot
Forum Updated to NodeBB v4.3 + New Features

QLabel won't update from Slot

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 1.1k Views 1 Watching
  • 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.
  • mrjjM mrjj

    Hi
    in this line
    connect(socket, SIGNAL(readyRead()), &mw, SLOT(fillText()));
    what is mw ?

    anyway, it sounds like the slot works so the connection is ok.

    so which part is not updating?
    itemLabel->setText sounds like its updating as you see the random number ?

    Ahh you mean how to read the actual massage from socket and pass that along ?

    R Offline
    R Offline
    rahulb1218
    wrote on last edited by
    #3

    @mrjj Hello, mw is a MainWindow object I initialized in the header file of this other class.

    So, qDebug tells me that the label's text value is indeed updating. However, in the actual GUI window, the the text for itemLabel remains "Label Created," which according to this line:

    qDebug() << "item Label's text: " + itemLabel->text();

    is not the case.

    No, I have not yet tried to work on the actual message, just trying to get the GUI to update when a message is received is my worry for now.

    mrjjM 1 Reply Last reply
    0
    • R rahulb1218

      @mrjj Hello, mw is a MainWindow object I initialized in the header file of this other class.

      So, qDebug tells me that the label's text value is indeed updating. However, in the actual GUI window, the the text for itemLabel remains "Label Created," which according to this line:

      qDebug() << "item Label's text: " + itemLabel->text();

      is not the case.

      No, I have not yet tried to work on the actual message, just trying to get the GUI to update when a message is received is my worry for now.

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #4

      @rahulb1218

      Hi
      But is this the classic gotcha then?

      You already have one mainwindow, you look at but then create a
      new one called mw (which you don't call show on) and you connect to that
      but its not the one that is actually showing ?

      To fix this , you can connect where you create the "otheclass" that has the socket

      like if you create it in Mainwindow

      TheOTherclass * other = new TheOTherclass(this)
      connect(other->socket, SIGNAL(readyRead()), this, SLOT(fillText()));

      R 1 Reply Last reply
      2
      • mrjjM mrjj

        @rahulb1218

        Hi
        But is this the classic gotcha then?

        You already have one mainwindow, you look at but then create a
        new one called mw (which you don't call show on) and you connect to that
        but its not the one that is actually showing ?

        To fix this , you can connect where you create the "otheclass" that has the socket

        like if you create it in Mainwindow

        TheOTherclass * other = new TheOTherclass(this)
        connect(other->socket, SIGNAL(readyRead()), this, SLOT(fillText()));

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

        @mrjj ohhhhh I see what I did now.
        How would I write this line since my other class has a qintptr argument:
        qDebug() << "item Label's text: " + itemLabel->text();

        mythread.h:

        #ifndef MYTHREAD_H
        #define MYTHREAD_H
        #include <QThread>
        #include <QTcpSocket>
        #include <QObject>
        #include "mainwindow.h"
        
        class MyThread : public QThread
        {
            Q_OBJECT
        public:
            explicit MyThread(qintptr ID, QObject *parent = 0);
            void run();
        signals:
            void error(QTcpSocket::SocketError socketerror);
        
        public slots:
            void readyRead();
            void disconnected();
        private:
            QTcpSocket *socket;
            qintptr socketDescriptor;
            MainWindow mw;
        };
        
        #endif // MYTHREAD_H
        
        

        mythread.cpp(contains old connect code, but I will take it out and put connect in MainWindow):

        #include "mythread.h"
        
        
        MyThread::MyThread(qintptr ID, QObject *parent) :
            QThread(parent)
        {
            this->socketDescriptor = ID;
        }
        
        void MyThread::run()
        {
            qDebug() << "Thread started";
            socket = new QTcpSocket();
        
            if(!socket->setSocketDescriptor(this->socketDescriptor))
                {
                    // something's wrong, we just emit a signal
                    emit error(socket->error());
                    return;
                }
            connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
            connect(socket, SIGNAL(readyRead()), &mw, SLOT(fillText()));
            connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
            qDebug() << socketDescriptor << " Client connected";
            exec();
        }
        void MyThread::readyRead()
        {
            QByteArray Data = socket->readAll();
            qDebug() << socketDescriptor << " Data in: " << Data;
            socket->write("Data reply: " + Data);
        }
        void MyThread::disconnected()
        {
            qDebug() << socketDescriptor << " Disconnected";
            socket->deleteLater();
            exit(0);
        }
        
        

        thank you so much!!

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

          Hi
          What about making a new signal like the
          void error(QTcpSocket::SocketError socketerror);

          but then instead

          void DataReady(QString text );

          and then in
          void MyThread::readyRead()
          {
          QByteArray Data = socket->readAll();
          qDebug() << socketDescriptor << " Data in: " << Data;
          socket->write("Data reply: " + Data);
          emit DataReady(QString(Data)); // we got something to show in MainWindow
          }

          and then in Mainwindow (the real one) you connect the new signal DataReady
          to some slot and there you do the itemLabel->text(); thing as MainWindow has that
          Qlabel and it's NOT allowed to fiddle with Widgets across threads and MyThread is such a beast so
          you should not call setText or any function on Widgets that are in MainWindow.

          Also, Do you really need a new Thread ?
          QTcpSocket is already async and will send signal when to read new data so
          it won't block the main GUI thread.
          If you later plan on doing heavy calculation/processing on the incoming data it's fine but
          just had to ask :)

          R 1 Reply Last reply
          3
          • mrjjM mrjj

            Hi
            What about making a new signal like the
            void error(QTcpSocket::SocketError socketerror);

            but then instead

            void DataReady(QString text );

            and then in
            void MyThread::readyRead()
            {
            QByteArray Data = socket->readAll();
            qDebug() << socketDescriptor << " Data in: " << Data;
            socket->write("Data reply: " + Data);
            emit DataReady(QString(Data)); // we got something to show in MainWindow
            }

            and then in Mainwindow (the real one) you connect the new signal DataReady
            to some slot and there you do the itemLabel->text(); thing as MainWindow has that
            Qlabel and it's NOT allowed to fiddle with Widgets across threads and MyThread is such a beast so
            you should not call setText or any function on Widgets that are in MainWindow.

            Also, Do you really need a new Thread ?
            QTcpSocket is already async and will send signal when to read new data so
            it won't block the main GUI thread.
            If you later plan on doing heavy calculation/processing on the incoming data it's fine but
            just had to ask :)

            R Offline
            R Offline
            rahulb1218
            wrote on last edited by rahulb1218
            #7

            @mrjj oh yes that would work, and I could probably manage with one thread but I will keep it like this for now and optimize later.
            So in MainWindow, I would do this:

            MyThread * other = new MyThread(this)
            connect(other, SIGNAL(dataReceived(QString Data??)), this, SLOT(fillText()));

            But how would I initialize “*other” since has a required arg? That is my confusion.

            I need other so I can specify the sender object.

            or do you mean DataReady signal should belong to MainWindow?

            My first QT and c++ project, sorry.

            mrjjM 1 Reply Last reply
            0
            • R rahulb1218

              @mrjj oh yes that would work, and I could probably manage with one thread but I will keep it like this for now and optimize later.
              So in MainWindow, I would do this:

              MyThread * other = new MyThread(this)
              connect(other, SIGNAL(dataReceived(QString Data??)), this, SLOT(fillText()));

              But how would I initialize “*other” since has a required arg? That is my confusion.

              I need other so I can specify the sender object.

              or do you mean DataReady signal should belong to MainWindow?

              My first QT and c++ project, sorry.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #8

              @rahulb1218

              Hi
              Yes but one never shows the param name in the connect so

              MyThread * other = new MyThread(this)
              connect(other, SIGNAL(dataReceived(QString)), this, SLOT(fillText()));

              ( I assume that dataReceived is your name for DataReady example)

              and you should change the filltext from

              void fillText()
              ->
              void fillText(QString data);

              As in - add new parameter to your slot, to use the data.

              • But how would I initialize “*other” since has a required arg? That is my confusion.

              You mean the connect or the
              MyThread * other = new MyThread(this)
              part ?

              • My first QT and c++ project, sorry.
                Then it goes pretty well I must say :)

              When you feel for it, you should have a look at the new way to connect
              https://wiki.qt.io/New_Signal_Slot_Syntax

              R 1 Reply Last reply
              1
              • mrjjM mrjj

                @rahulb1218

                Hi
                Yes but one never shows the param name in the connect so

                MyThread * other = new MyThread(this)
                connect(other, SIGNAL(dataReceived(QString)), this, SLOT(fillText()));

                ( I assume that dataReceived is your name for DataReady example)

                and you should change the filltext from

                void fillText()
                ->
                void fillText(QString data);

                As in - add new parameter to your slot, to use the data.

                • But how would I initialize “*other” since has a required arg? That is my confusion.

                You mean the connect or the
                MyThread * other = new MyThread(this)
                part ?

                • My first QT and c++ project, sorry.
                  Then it goes pretty well I must say :)

                When you feel for it, you should have a look at the new way to connect
                https://wiki.qt.io/New_Signal_Slot_Syntax

                R Offline
                R Offline
                rahulb1218
                wrote on last edited by rahulb1218
                #9

                @mrjj

                MyThread * other = new MyThread(this)
                When I use this, I get the "no matching constructor for initialization of "MyThread." I think this is because the param needs to be of type qintptr, right?

                So I tried something. I tried to grab the MyThread object that is initialized in my server files header. I will attach. I used extern and added this line to my mainwindow.cpp. However, this would give me linker error when compiling.

                myserver.h:

                #ifndef MYSERVER_H
                #define MYSERVER_H
                #include <QTcpServer>
                
                class MyServer : public QTcpServer
                {
                    Q_OBJECT
                public:
                    MyServer(QObject *parent = 0);
                    void startServer();
                protected:
                    void incomingConnection(qintptr socketDescriptor);
                };
                
                #endif // MYSERVER_H
                
                

                myserver.cpp:

                #include "myserver.h"
                #include "mythread.h"
                
                MyServer::MyServer(QObject *parent) :
                    QTcpServer(parent)
                {
                
                }
                void MyServer::startServer()
                {
                    int port = 1234;
                    if(!this->listen(QHostAddress::Any, port))
                        {
                            qDebug() << "Could not start server";
                        }
                        else
                        {
                            qDebug() << "Listening to port " << port << "...";
                        }
                }
                void MyServer::incomingConnection(qintptr socketDescriptor)
                {
                    // We have a new connection
                    qDebug() << socketDescriptor << " Connecting...";
                
                    MyThread *threadly = new MyThread(socketDescriptor, this);
                
                    // connect signal/slot
                    // once a thread is not needed, it will be beleted later
                    connect(threadly, SIGNAL(finished()), threadly, SLOT(deleteLater()));
                
                    threadly->start();
                }
                
                

                In mainwindow.cpp, I added

                extern const MyThread* threadly;
                

                and

                connect(threadly, SIGNAL(dataSignal()), this, SLOT(fillText()));
                

                It would give a linker error at this line. I read online that I must #include mainwindow.moc, but QT could not find that file.

                However, if you believe that this is the wrong way to tackle this, and instead initialize another MyThread object in mainwindow, I will do that instead, but the correct way as using (this) as the param does not work for me.

                And again, thank you so much for the help!

                PS: the error detail for using MyThread(this) is: no matching constructor for initialization of 'MyThread'
                note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'MainWindow *' to 'const MyThread' for 1st argument
                note: candidate constructor not viable: no known conversion from 'MainWindow *' to 'qintptr' (aka 'long long') for 1st argument

                JonBJ 1 Reply Last reply
                0
                • R rahulb1218

                  @mrjj

                  MyThread * other = new MyThread(this)
                  When I use this, I get the "no matching constructor for initialization of "MyThread." I think this is because the param needs to be of type qintptr, right?

                  So I tried something. I tried to grab the MyThread object that is initialized in my server files header. I will attach. I used extern and added this line to my mainwindow.cpp. However, this would give me linker error when compiling.

                  myserver.h:

                  #ifndef MYSERVER_H
                  #define MYSERVER_H
                  #include <QTcpServer>
                  
                  class MyServer : public QTcpServer
                  {
                      Q_OBJECT
                  public:
                      MyServer(QObject *parent = 0);
                      void startServer();
                  protected:
                      void incomingConnection(qintptr socketDescriptor);
                  };
                  
                  #endif // MYSERVER_H
                  
                  

                  myserver.cpp:

                  #include "myserver.h"
                  #include "mythread.h"
                  
                  MyServer::MyServer(QObject *parent) :
                      QTcpServer(parent)
                  {
                  
                  }
                  void MyServer::startServer()
                  {
                      int port = 1234;
                      if(!this->listen(QHostAddress::Any, port))
                          {
                              qDebug() << "Could not start server";
                          }
                          else
                          {
                              qDebug() << "Listening to port " << port << "...";
                          }
                  }
                  void MyServer::incomingConnection(qintptr socketDescriptor)
                  {
                      // We have a new connection
                      qDebug() << socketDescriptor << " Connecting...";
                  
                      MyThread *threadly = new MyThread(socketDescriptor, this);
                  
                      // connect signal/slot
                      // once a thread is not needed, it will be beleted later
                      connect(threadly, SIGNAL(finished()), threadly, SLOT(deleteLater()));
                  
                      threadly->start();
                  }
                  
                  

                  In mainwindow.cpp, I added

                  extern const MyThread* threadly;
                  

                  and

                  connect(threadly, SIGNAL(dataSignal()), this, SLOT(fillText()));
                  

                  It would give a linker error at this line. I read online that I must #include mainwindow.moc, but QT could not find that file.

                  However, if you believe that this is the wrong way to tackle this, and instead initialize another MyThread object in mainwindow, I will do that instead, but the correct way as using (this) as the param does not work for me.

                  And again, thank you so much for the help!

                  PS: the error detail for using MyThread(this) is: no matching constructor for initialization of 'MyThread'
                  note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'MainWindow *' to 'const MyThread' for 1st argument
                  note: candidate constructor not viable: no known conversion from 'MainWindow *' to 'qintptr' (aka 'long long') for 1st argument

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #10

                  @rahulb1218
                  You have said:

                  My first QT and c++ project, sorry.

                  @mrjj oh yes that would work, and I could probably manage with one thread but I will keep it like this for now and optimize later.

                  Why in the world are you soldiering on using threads? They are probably the single hardest part of Qt (or other toolkit) to get right, and you are now having problems with them. I would not dream of using threads if I were new to C++ & Qt.

                  I don't know what you are trying to achieve but these Fortune examples do QTcpSocket without any threads:

                  • Fortune Client Example
                  • Fortune Server Example

                  If you do want (really need!) to use threads have you had a look at:

                  • Threaded Fortune Server Example
                  R 1 Reply Last reply
                  4
                  • JonBJ JonB

                    @rahulb1218
                    You have said:

                    My first QT and c++ project, sorry.

                    @mrjj oh yes that would work, and I could probably manage with one thread but I will keep it like this for now and optimize later.

                    Why in the world are you soldiering on using threads? They are probably the single hardest part of Qt (or other toolkit) to get right, and you are now having problems with them. I would not dream of using threads if I were new to C++ & Qt.

                    I don't know what you are trying to achieve but these Fortune examples do QTcpSocket without any threads:

                    • Fortune Client Example
                    • Fortune Server Example

                    If you do want (really need!) to use threads have you had a look at:

                    • Threaded Fortune Server Example
                    R Offline
                    R Offline
                    rahulb1218
                    wrote on last edited by
                    #11

                    @JonB

                    I'm working on a project where I need to able to send a string from one device to another. So, the first thing I did was look up was examples of one script talking to another. One of the first ones I found used threads. I will however try this, thank you!

                    JonBJ 1 Reply Last reply
                    0
                    • R rahulb1218

                      @JonB

                      I'm working on a project where I need to able to send a string from one device to another. So, the first thing I did was look up was examples of one script talking to another. One of the first ones I found used threads. I will however try this, thank you!

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #12

                      @rahulb1218
                      Depends whether these "scripts" were for Qt or not. Qt's TCP/socket code is inherently asynchronous, whereas other examples/toolkits are likely to be synchronous and so require threads.

                      I did not say using threads was necessarily wrong (depends exactly what you have to do in your proposed thread). What I did say is that if I were new to both Qt & C++ I would not choose to use threading if I could possibly help 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