如何修改来自不同 class QT/C++ 的动态创建的 Widget 的值
how to modify values of dynamically created Widget from different class QT/C++
我知道这个问题已被问过几次,但那里给出的所有建议对我都不起作用。
概述: 我正在实施客户端服务器模型,并希望一旦消息到达服务器,它就应该显示在主 Qt 小部件中。 widget,我选择显示msg的是QLineEdit。
目前我的项目中有 3 个文件。 Agent_A 这是动态创建的所有小部件。然后Server_test基于QTCPServer和sockClient进行socket连接。我已从客户端成功收到有关 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() );
}
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 );
}
能否请您先检查一下 parent 是否不为 NULL?
您能否展示创建 SockClient 实例的代码?
当然,你不能修改文本,因为你设置为 socketClient
object this
pointer in Server_test
class 的父对象,所以父对象为 socketClient
将是 Server_test
但不是 Agent_A
。
所以为 socketClient
对象设置父对象 Agent_A
:
socketforClient = new SockClient(this->parent(), server->nextPendingConnection());
或者您可以制定其他一些解决方法。
还有一个 注意:您在 startServer
方法而不是构造函数中连接到 newConnection()
信号。因此,如果我启动服务器,然后停止它们并再次启动,服务器将连接两次以发出信号,并且插槽 incomingConnection()
也将被调用两次。因此,您需要在 stopServer()
方法中断开信号或在 class 的构造函数中进行连接或使用 Qt::UniqueConnection
.
这是一个非常简单的例子:
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;
}
我知道这个问题已被问过几次,但那里给出的所有建议对我都不起作用。
概述: 我正在实施客户端服务器模型,并希望一旦消息到达服务器,它就应该显示在主 Qt 小部件中。 widget,我选择显示msg的是QLineEdit。
目前我的项目中有 3 个文件。 Agent_A 这是动态创建的所有小部件。然后Server_test基于QTCPServer和sockClient进行socket连接。我已从客户端成功收到有关 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() );
}
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 );
}
能否请您先检查一下 parent 是否不为 NULL? 您能否展示创建 SockClient 实例的代码?
当然,你不能修改文本,因为你设置为 socketClient
object this
pointer in Server_test
class 的父对象,所以父对象为 socketClient
将是 Server_test
但不是 Agent_A
。
所以为 socketClient
对象设置父对象 Agent_A
:
socketforClient = new SockClient(this->parent(), server->nextPendingConnection());
或者您可以制定其他一些解决方法。
还有一个 注意:您在 startServer
方法而不是构造函数中连接到 newConnection()
信号。因此,如果我启动服务器,然后停止它们并再次启动,服务器将连接两次以发出信号,并且插槽 incomingConnection()
也将被调用两次。因此,您需要在 stopServer()
方法中断开信号或在 class 的构造函数中进行连接或使用 Qt::UniqueConnection
.
这是一个非常简单的例子:
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;
}