Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

accessing and reading public variable of object1 from another object2 or object3



  • i have a multi threaded client to server QT code which is working fine. each client connected will run on its own thread. in the code , i have a TCP_Server class (QTcpServer), a Connection_Thread class (Qthread), A Data_process class(QObject) and also a Frontpage class (Qwidget).

    The Frontpage consist of just label which will display "server is running" when the server is started, and also another label which displays the number of client connected to it. so each time a client connects or disconnects, the label must be updated. The Data_process class is to process the received client data.

    As im trying now to count the number of client connected to the server and display it in the frontpage, to achieve this i use a suggestion i found in stackoverflow website as below:-

    =>for each command you receive from a client, you add/update a Map entry
    =>this map entry has the socket descriptor as key and a timestamp as value.
    =>Now you can regularly recheck the map and remove entries that are too old.
    =>QMap::count() gives you the number of connected and active clients.
    =>you can also attach a signal to the socket::disconnect() signal and remove the entry from the map

    so in the TCP_Server class i added another public variable as below:-

    QMap<qintptr,QDateTime>clientcameramap;  
    

    and on the TCP_Server::incomingConnection(qintptr socketDescriptor) functions, added this code:-

    clientcameramap.insert(socketDescriptor,Datetime.currentDateTime()); 
    

    so each time a new connection is made it will be loaded in the Qmap, and also in the "incomingConnection" functions, a new thread will be created when a client connects to the server.

    my problem is now how to remove the connected clients from the Qmap declared in the TCP_server class whenever a client disconnects, as the disconnect part of the code is on the Connection_Thread::run() functions. The TCP_server class object is created on the mainwindows.cpp code as below:-

     m_server = new TCP_Server(m_process_data,this);
    

    now i not sure how to access the "clientcameramap" variable in the TCP_Server object from the client-threads from its run() functions when a disconnect signal is received by the thread. In the existing Connection_Thread::run() code there exist a signal slot functions as below:-

    connect(socket, SIGNAL(disconnected()), this, SLOT(Disconnected()));
    

    The problem i just cant write another signal & slot code in the Connection_Thread::run() as below:

    connect(socket, SIGNAL(disconnected()), m_server, SLOT(ClientDisconnected()));
    

    this will not works because the "m_server" object is created on the mainwindows.cpp and so how make the TCP_server object "m_server" to be "visible/available/accessible" to the running threads run() functions??

    what approach i should take?? and i also finally need to pass the result i get from:

    m_server->clientcameramap.count() 
    

    to the Frontpage labels to update the latest count.The Frontpage object is also created in the mainwindows.cpp.

    so basically i need to access the "clientcameramap" public variable of the TCP_server class by the Frontpage object and Connections_threads.

    below are the relevant code sections:-

    My TCP_server codes

    void TCP_Server::incomingConnection(qintptr socketDescriptor)
    {
        QDateTime Datetime;
    
        qDebug() << socketDescriptor << " Connecting...";
    
       //map&track the new client connection
       clientcameramap.insert(socketDescriptor,Datetime.currentDateTime());
    
     Connection_Thread *thread = new Connection_Thread(socketDescriptor, m_data_process,this);
    
     //once a thread is not needed, it will be deleted
     connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    
     //connect signal/slot of the thread 
    connect(thread,SIGNAL(status(APC_CAMERA_DATA)),this,SLOT(Get_Status(APC_CAMERA_DATA)));
    
        thread->start();
    }
    

    My Connection Threads::run() codes:-

    void Connection_Thread::run()
    {
        //qDebug() << " Thread started"; /<<--original
          qDebug()<<"Thread started for:"<<this->socket_descriptor;
    
        socket = new QTcpSocket();  //
    
        // set the ID
        if(!socket->setSocketDescriptor(this->socket_descriptor))
        {
            //emit a signal when error occur
            emit error(socket->error());
            return;
        }
    
    connect(socket, SIGNAL(readyRead()), this, SLOT(Ready_Read()), Qt::DirectConnection); //<<----- original
      
    connect(socket, SIGNAL(disconnected()), this, SLOT(Disconnected()));/
    
    /*how use signal slot here to connect the socket disconnect signal and call a 
     slot in the TCP_server object (m_server) to remove the client from the Qmap*/ 
    
        qDebug() << socket_descriptor << "Client connected";
    
        //----------Newly added test codes for reading clientip 101219----
         /*to read the ip address of the connected client*/
         qDebug()<<"Client Ip address"<<socket->peerAddress().toString();
         qDebug()<<"client Port"<<socket->peerPort();
    
        exec(); //<<----- original
    }
    


  • try out:

    in Connection_Thread.h add:

    signals:
    void thread_is_out (qintptr descriptor);
    

    in Connection_Thread.cpp (slot Disconnected):

    void Connection_Thread::Disconnected ()
    {
     //run yours codes
      emit thread_is_out (this->socket_descriptor);
    }
    

    in TCP_Server.cpp :

    void TCP_Server::incomingConnection(qintptr socketDescriptor)
    {
      //add
     connect(thread, SIGNAL(thread_is_out (qintptr)), this, SLOT(create_on_function(qintptr)));
    }
    
    void TCP_Server::create_on_function(qintptr key)
    { 
    clientcameramap.erase(clientcameramap.find(key));
    //or
    clientcameramap.remove(key);
    
    //and what you want to do
    }
    

    just try out!!!


  • Lifetime Qt Champion

    Apart from the real problem - why do you need threading here at all? Do you process large data somewhere?



  • @Christian-Ehrlicher said in accessing and reading public variable of object1 from another object2 or object3:

    Apart from the real problem - why do you need threading here at all? Do you process large data somewhere?

    actually the original code already use threading, i just adding stuff to the original code and modifying it according to my needs now.....actually the client is a camera that will send some data to the server which will process using the Data_process class. i dont want to change the architecture as it is already working, now i just need add a extra thing to count the number of clients.


  • Lifetime Qt Champion

    There is no need to emit a signal from within the thread since you can count it inside TCP_Server::incomingConnection() - you even already have the count there - in clientcameramap.



  • try out:

    in Connection_Thread.h add:

    signals:
    void thread_is_out (qintptr descriptor);
    

    in Connection_Thread.cpp (slot Disconnected):

    void Connection_Thread::Disconnected ()
    {
     //run yours codes
      emit thread_is_out (this->socket_descriptor);
    }
    

    in TCP_Server.cpp :

    void TCP_Server::incomingConnection(qintptr socketDescriptor)
    {
      //add
     connect(thread, SIGNAL(thread_is_out (qintptr)), this, SLOT(create_on_function(qintptr)));
    }
    
    void TCP_Server::create_on_function(qintptr key)
    { 
    clientcameramap.erase(clientcameramap.find(key));
    //or
    clientcameramap.remove(key);
    
    //and what you want to do
    }
    

    just try out!!!



  • This post is deleted!


  • @Lemat

    //additional
    here is my code to destroy all threads after server stopped

    QList <QThread*> thread_list=TCP_Server::findChildren <QThread*>();
    foreach (QThread *elem, thread_list) elem->exit(0);
    


  • @Christian-Ehrlicher said in accessing and reading public variable of object1 from another object2 or object3:

    There is no need to emit a signal from within the thread since you can count it inside TCP_Server::incomingConnection() - you even already have the count there - in clientcameramap.

    yup i already can count , but now let say some clients got disconnected, then i will need to remove the client from the clientcameramap right, and then i need to update to the frontpage object so that it can refresh the label.

    For this i created a "Clientdisconnected" slot in the TCP_server to remove the client from the map, as per that if u refer my Connection_Thread::run() functions, once a client signals disconnect, i want call the slot to remove the clients, only this part i confuse because the TCP_server object is created on the mainwindows.cpp, so i cant connect the client disconnect signal to the TCP_server objects slot.


  • Lifetime Qt Champion

    @VikramSamy said in accessing and reading public variable of object1 from another object2 or object3:

    but now let say some clients got disconnected,

    Then you should update your clientcameramap (already now) - otherwise you've old stuff in this map and it's useless. Since you know when a client is disconnected (I assume that you close the thread in Disconnected()) you can watch on the QThread::finished() signal.



  • @VikramSamy

    You could watch the Qthread::finished() signal.
    Disconnect = Call Exit Thread
    Remove the item from Map as mentioned by Lemant and finally emit a signal from TCP_Server to update the count on frontpage label.



  • @Lemat @Christian-Ehrlicher @KillerSmath

    yup it works! thanks, so each time a client connects & diconnects i can know the count, so now im trying pass the count value to the FrontPage Object which is created in the mainwindow.cpp

     FP = new FrontPage(this);  // at mainwindows.cpp
    

    the Frontpage class.h is as below:-

    class FrontPage : public QWidget
    {
        Q_OBJECT
    public:
        explicit FrontPage(QWidget *parent = 0);
        void ServerStatus (bool status);
        QLabel      *serverstatuslabel;
        QLabel      *clientconnectedlabel;
        QLabel      *ServerIPaddr;
        QLabel      *ServerPORTno;
        QLabel      *infolabel;
        QLabel      *clientcount;
    
    signals:
    
    public slots:
        void ClientCount(unsigned int count);
    
    private:
        QVBoxLayout  *vboxlayout;
    };
    
    

    so i need to emit signal at TCP_Server::incomingConnection , and connect it to the FrontPage slots: FrontPage::ClientCount(unsigned int count) then i should also emit a signal from the TCP_Server::ClientDisconnected after removing the client from the clientcameramap to the same slot FrontPage::ClientCount(unsigned int count), so this way i can pass around the count value to be refreshed at the Frontpage label each time a connects/disconnects happens...
    But like just now the FrontPage is created in mainwindows.cpp, as per that the frontpage object not visible/accessible to the TCP_server, how to go around with this?? this where i still not much understand... can u tell something about this?? my FrontPage is slot code is as below:-

     void FrontPage::ClientCount(unsigned int count)
      {
          QString tmp = QString::number(count);
          QString Stringtext;
    
          Stringtext = "number of client connected is = %1";
    
          clientconnectedlabel->setText(Stringtext.arg(tmp));
    
          //QString tmp = QString::number(myInt)
          //QString tmp = tr("%1").arg(myInt)
      }
    

    but i need a proper way to connect both signals emitted from TCP_Server::incomingConnections and TCP_Server::ClientDisconnected to the FrontPage slot.

    below is some part of my related mainwindows.cpp code:-

    FP = new FrontPage(this);
    m_server = new TCP_Server(m_process_data,this);                                                                       
    
         if(m_server->Start_Server())
         {      connect(m_server,SIGNAL(status(APC_CAMERA_DATA)),m_sql_process,SLOT(Store_APC_CAMERA_DATA(APC_CAMERA_DATA)));
             FP->ServerStatus(true);
         }
         else
         {
             FP->ServerStatus(false);
         }
    
        setCentralWidget(FP);
    /*so this FP is just a gui widget display the server is running and number of clients connected to it*/
    


  • @KillerSmath said in accessing and reading public variable of object1 from another object2 or object3:

    finally emit a signal from TCP_Server to update the count on frontpage label.

    The problem is , i can emit signal from TCP_server to update the count on the FrontPage label, as i just explain in my previous post.. and i also already created the slot functions of FrontPage, and this slot should connected with the TCP_server signal for update, now here is problem, the signal & slot need Object1 (TCP_server) and Object 2 (FrontPage), and as FrontPage object is created on the mainwindow.cpp, im stuck on how make this to work coz FrontPage object is not available/visible to TCP_Server,


  • Lifetime Qt Champion

    @VikramSamy Is TCP_Server accessible in main window? If so do the connection there.


Log in to reply