Search code examples
c++qtqwidget

how to modify values of dynamically created Widget from different class QT/C++


I know this question has been asked few times but all suggestions given there doesn't work for me.

Overview: I am implementing client server model and wants that as soon as msg arrived in server it should get displayed in main Qt widget. the widget , I choose to display msg is QLineEdit.

I have 3 files in project at the moment. Agent_A which is has all widget created dynamically. Then Server_test based on QTCPServer and sockClient for socket connection. I have received message on sockclient successfully from client but I don't know how to display it correctly on Agent_A .

I have added function in socketClient.cpp to update function in Agent_A but I guess when creating instance it always being NULL.

First a small snippet of my code and then what I have tried. may be you guys can input some valuable info.

Agent_A.h

class Agent_A : public QWidget
{
    Q_OBJECT

public:
    explicit Agent_A(QWidget *parent = 0);
     void setLineEdit( const& modifyStr ); // function to change lineEditCmdString
    ~Agent_A();

private:
    Ui::Agent_A *ui;
    QPushButton   *buttonStartServer;
    QPushButton   *buttonStopServer;
    // some other widgets 
    QLabel        *labelDisplay;
    QLineEdit     *lineEditCmdString;// I want to modify this value from sock client
    ServerTest   *server;

// few slots defined here
}

Agent_A.cpp

Agent_A::Agent_A( QWidget *parent ):
           QWidget( parent ),
           ui( new Ui::Agent_A )
{

  //define push buttons
  buttonStartServer = new QPushButton( tr( "&Start Server" ) );
  buttonStopServer  = new QPushButton( tr( "S&top" ));

  // some properties of other widgets defined here which is not relevant to mention here

  labelDisplay      = new QLabel( tr("DisplayMessgae" ) );
  lineEditCmdString    = new QLineEdit;// I want to modify this value on sock client
  labelDisplay->setBuddy( lineEditCmdString );

  // define signals and slots for Server
  connect( buttonStartServer, SIGNAL( clicked() ), this, SLOT( startServers() ) );
  connect( buttonStopServer,  SIGNAL( clicked() ), this, SLOT( stopServer()  ) );


// some layout here  which agian is not important to mention here.
 ui->setupUi( this );
}

Agent_A::~Agent_A()
{
    delete ui;
}

void Agent_A::setLineEdit( const Qstring& modifyStr )
{
   lineEditCmdString->setText( modifyStr );
}

// now by socket client which creates socket sockClient.h

class SockClient : public QObject
{
  Q_OBJECT
public:
 explicit  SockClient( QObject *parent, QTcpSocket* socket= 0 );

 ~SockClient();

// I have added this function to update QLIneEdit in Agent_A
 void updateTextinParent(const QString &changeText);

signals:

private slots:
  void readClient();

private:
 // some other functions

  QTcpSocket *socketClient;
  quint16 nextBlockSize;

public slots:
};

sockclient.cpp

// constructor for sockclient and some other functions


SockClient::SockClient( QObject *parent, QTcpSocket* socket ) : QObject( parent )

{
   socketClient =  socket ;
  // create signals and slots
  connect( socketClient, SIGNAL( readyRead() ),    this, SLOT( readClient()  ) );
  connect( socketClient, SIGNAL( disconnected() ), this, SLOT( deleteLater() ) );

}

SockClient::~SockClient()
{
  socketClient->close();
  delete socketClient;
}

void SockClient::readClient()
{


  QDataStream clientReadStream( socketClient );
  clientReadStream.setVersion( QDataStream::Qt_4_3 );

  QString strRecvFrm;
  quint8 requestType;
  clientReadStream >> nextBlockSize;
  clientReadStream >> requestType;
  if( requestType == 'S')
    {

      clientReadStream >> strRecvFrm;
    }

  qDebug() << " the string is " << strRecvFrm; // Has recieved correctly from client
  updateTextinParent( strRecvFrmMops ); // Now trying to update widget

  socketClient->close();
}



 void SockClient::updateTextinParent( const QString& changeText )
    {

 if( this->parent() == 0 )
{
  qDebug() << " Parent not assigned"; // This get printed ..
}
      Agent_A *agent = qobject_cast< Agent_A* >( this->parent() ); // ?? is this is right way to do..?
      if( agent != NULL )
        {
          qDebug() << " we are in updateTextin" << changeText; // it never get printed so I assume  instance is always nULL
           agent->setLineEdit( changeText );
        }

    }

// ServerTest.cpp where instance of sockClient is created

    ServerTest::ServerTest(QObject *parent) : QObject(parent)
    {
      server = new QTcpServer( this ); 
    }

    void ServerTest::startServer()
    {
      connect( server, SIGNAL( newConnection() ), this, SLOT( incomingConnection() ) );
      if( !server->listen( QHostAddress::Any, 9999) )
      {
        qDebug() << " Server failed to get started";
      }
      else
      {
       qDebug() << " Server started";
      }
    }


    void ServerTest::stopServer()
    {
      server->close();
      qDebug() << "Server closed";
    }

    ServerTest::~ServerTest()
    {
      server->close();
      delete socketforClient;
      delete server;
    }

    void ServerTest::incomingConnection()
    {
      socketforClient = new SockClient(this->parent(), server->nextPendingConnection() );
    }

Solution

  • This is a very simple example:

    qt.pro:

    TEMPLATE = app
    TARGET = 
    DEPENDPATH += .
    INCLUDEPATH += .    
    # Input
    HEADERS += classes.h
    SOURCES += main.cpp
    

    classes.h:

    #include <QObject>
    #include <QDebug>
    
    class Agent_A : public QObject
    {
        Q_OBJECT
    
        public slots:
        void updateText(const QString &changeText) {
            qDebug() << "updateText: " << changeText;
        };
    };
    
    class SockClient : public QObject
    {
        Q_OBJECT
    
        signals:
        void updateTextinParent(const QString &text);
     public:
        void incomingText(const QString &text) {
            emit updateTextinParent(text);
        };
    };
    

    main.cpp:

    #include "classes.h"
    
    int main(int argc, char **argv) {
        Agent_A *agent = new Agent_A;
        SockClient client;
    
        QObject::connect(&client, SIGNAL(updateTextinParent(const QString &)),
                         agent, SLOT(updateText(const QString &)));
    
        client.incomingText(QString("hello"));
    
        return 0;
    }