如何修改来自不同类QT/C++的动态创建的Widget的值



我知道这个问题已经被问了好几次了,但所有给出的建议都对我无效。

概述:我正在实现客户端-服务器模型,并希望一旦消息到达服务器,它就应该显示在主Qt小部件中。我选择显示消息的小部件是QLineEdit。

我目前有3个文件在项目中。Agent_A动态创建所有小部件。然后基于QTCPServer和sockClient进行Server_test套接字连接。我在sockclient上成功地收到了来自客户端的消息,但我不知道如何在Agent_A上正确显示它。

我在socketClient.cpp中添加了函数来更新Agent_A中的函数,但我想在创建实例时它总是为NULL。

首先是我的一小段代码,然后是我尝试过的。也许你们可以输入一些有价值的信息。

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 );
}

//现在由创建套接字的套接字客户端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() );
    }

这是一个非常简单的例子:

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;
}
    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( chnageText );
    }

你能先检查一下父项是否为NULL吗?您能展示一下您在哪里创建SockClient实例的代码吗?

当然,您不能修改文本,因为您在Server_test类中将socketClient对象this指针设置为父对象,所以socketClient的父对象将是Server_test,而不是Agent_A

因此,为socketClient对象制作父Agent_A

socketforClient = new SockClient(this->parent(), server->nextPendingConnection());

或者你可以做一些其他的变通办法。

还有一个注意:您在startServer方法中连接到newConnection()信号,而不是构造函数。所以,如果我启动服务器,然后停止它们并重新启动,服务器将连接两次以发出信号,插槽incomingConnection()也将被调用两次。所以您需要在stopServer()方法中断开at与信号的连接,或者在类的构造函数中进行连接,或者使用Qt::UniqueConnection

相关内容

  • 没有找到相关文章

最新更新