qt使用c++创建多线程聊天室的完整代码
时间: 2023-12-24 14:05:46 浏览: 148
下面是一个简单的Qt多线程聊天室的完整代码示例:
```c++
#include <QtWidgets>
#include <QtNetwork>
class Server : public QTcpServer
{
Q_OBJECT
public:
explicit Server(QObject *parent = nullptr)
: QTcpServer(parent)
{
listen(QHostAddress::Any, 1234);
}
signals:
void newConnection(QTcpSocket *socket);
protected:
void incomingConnection(qintptr handle) override
{
auto *socket = new QTcpSocket(this);
socket->setSocketDescriptor(handle);
emit newConnection(socket);
}
};
class Client : public QObject
{
Q_OBJECT
public:
explicit Client(QTcpSocket *socket, QObject *parent = nullptr)
: QObject(parent)
, m_socket(socket)
{
connect(m_socket, &QTcpSocket::readyRead, this, &Client::readData);
connect(m_socket, &QTcpSocket::disconnected, this, &Client::disconnected);
}
signals:
void messageReceived(const QString &message);
public slots:
void sendMessage(const QString &message)
{
m_socket->write(message.toUtf8());
}
private slots:
void readData()
{
auto message = m_socket->readAll();
emit messageReceived(QString::fromUtf8(message));
}
void disconnected()
{
m_socket->deleteLater();
emit messageReceived(tr("Client disconnected"));
}
private:
QTcpSocket *m_socket;
};
class ChatServer : public QWidget
{
Q_OBJECT
public:
explicit ChatServer(QWidget *parent = nullptr)
: QWidget(parent)
{
m_server = new Server(this);
connect(m_server, &Server::newConnection, this, &ChatServer::handleNewConnection);
m_messageList = new QListWidget(this);
m_messageEdit = new QLineEdit(this);
connect(m_messageEdit, &QLineEdit::returnPressed, this, &ChatServer::sendMessage);
auto *layout = new QVBoxLayout(this);
layout->addWidget(m_messageList);
layout->addWidget(m_messageEdit);
}
private slots:
void handleNewConnection(QTcpSocket *socket)
{
auto *client = new Client(socket, this);
m_clients.append(client);
connect(client, &Client::messageReceived, this, &ChatServer::handleMessageReceived);
connect(client, &Client::messageReceived, client, &Client::sendMessage);
connect(client, &Client::messageReceived, this, &ChatServer::displayMessage);
connect(client, &Client::destroyed, this, &ChatServer::handleClientDestroyed);
displayMessage(tr("New client connected"));
}
void handleMessageReceived(const QString &message)
{
auto sender = qobject_cast<Client *>(sender());
if (!sender) {
return;
}
QString displayMessage = sender->objectName() + ": " + message;
emit messageReceived(displayMessage);
}
void handleClientDestroyed(QObject *object)
{
auto client = qobject_cast<Client *>(object);
if (!client) {
return;
}
m_clients.removeAll(client);
}
void sendMessage()
{
QString message = m_messageEdit->text();
emit messageReceived(QString("Server: %1").arg(message));
for (auto *client : m_clients) {
client->sendMessage(message);
}
m_messageEdit->clear();
}
void displayMessage(const QString &message)
{
m_messageList->addItem(message);
}
signals:
void messageReceived(const QString &message);
private:
Server *m_server;
QList<Client *> m_clients;
QListWidget *m_messageList;
QLineEdit *m_messageEdit;
};
class ChatClient : public QWidget
{
Q_OBJECT
public:
explicit ChatClient(QWidget *parent = nullptr)
: QWidget(parent)
{
m_socket = new QTcpSocket(this);
connect(m_socket, &QTcpSocket::readyRead, this, &ChatClient::readData);
connect(m_socket, &QTcpSocket::connected, this, &ChatClient::connected);
connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
m_messageList = new QListWidget(this);
m_messageEdit = new QLineEdit(this);
connect(m_messageEdit, &QLineEdit::returnPressed, this, &ChatClient::sendMessage);
auto *layout = new QVBoxLayout(this);
layout->addWidget(m_messageList);
layout->addWidget(m_messageEdit);
auto *button = new QPushButton(tr("Connect"), this);
connect(button, &QPushButton::clicked, this, &ChatClient::connectToServer);
layout->addWidget(button);
}
private slots:
void connectToServer()
{
m_socket->connectToHost(QHostAddress::LocalHost, 1234);
}
void connected()
{
displayMessage(tr("Connected to server"));
}
void sendMessage()
{
QString message = m_messageEdit->text();
m_socket->write(message.toUtf8());
m_messageEdit->clear();
}
void readData()
{
auto message = m_socket->readAll();
displayMessage(QString::fromUtf8(message));
}
void displayError(QAbstractSocket::SocketError error)
{
auto errorMessage = m_socket->errorString();
displayMessage(QString("Error: %1").arg(errorMessage));
}
void displayMessage(const QString &message)
{
m_messageList->addItem(message);
}
private:
QTcpSocket *m_socket;
QListWidget *m_messageList;
QLineEdit *m_messageEdit;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ChatServer server;
server.show();
ChatClient client;
client.show();
return a.exec();
}
#include "main.moc"
```
这个示例演示了如何创建一个简单的多线程聊天室。聊天室由一个服务器和一个客户端组成,使用QTcpSocket进行通信。服务器使用QTcpServer监听传入的连接,并在每次连接时创建一个Client对象,用于处理客户端发送的消息。客户端连接到服务器,然后可以发送消息并接收其他客户端发送的消息。注意,这个示例只是一个简单的演示,实际的聊天室需要更多的功能和错误处理。
阅读全文