commit 89b4182e6c17d949e50e794f81824129831d39d4
Author: Msy-msu <2200456405@qq.com>
Date: Thu Jan 5 20:52:31 2023 +0800
first commit
diff --git a/TcpClient.pro b/TcpClient.pro
new file mode 100644
index 0000000..a04066e
--- /dev/null
+++ b/TcpClient.pro
@@ -0,0 +1,39 @@
+QT += core gui network
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ main.cpp \
+ login.cpp \
+ datamanager.cpp \
+ mainwidget.cpp \
+ protocol.cpp \
+ signup.cpp \
+ tcpclient.cpp
+
+HEADERS += \
+ login.h \
+ datamanager.h \
+ mainwidget.h \
+ protocol.h\
+ signup.h \
+ tcpclient.h
+
+FORMS += \
+ login.ui \
+ mainwidget.ui \
+ signup.ui
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+RESOURCES += \
+ imgs/imgs.qrc
diff --git a/TcpClient.pro.user b/TcpClient.pro.user
new file mode 100644
index 0000000..fdb8bef
--- /dev/null
+++ b/TcpClient.pro.user
@@ -0,0 +1,432 @@
+
+
+
+
+
+ EnvironmentId
+ {d3fed20c-1c94-44fc-8f6a-4dbf39b54775}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ false
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ false
+ 1
+ true
+ true
+ true
+ *.md, *.MD, Makefile
+ false
+ true
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+ true
+ false
+ true
+ true
+ true
+ true
+
+
+ 0
+ true
+
+ -fno-delayed-template-parsing
+
+ true
+ Builtin.BuildSystem
+
+ true
+ true
+ Builtin.DefaultTidyAndClazy
+ 4
+
+
+
+ true
+
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop
+ Desktop Qt 6.2.3 MinGW 64-bit
+ Desktop Qt 6.2.3 MinGW 64-bit
+ qt.qt6.623.win64_mingw_kit
+ 0
+ 0
+ 0
+
+ 0
+ C:\Users\25761\Desktop\build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Debug
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Debug
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+
+
+ C:\Users\25761\Desktop\build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Release
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Release
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+
+
+ 0
+ C:\Users\25761\Desktop\build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Profile
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Profile
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+ 0
+
+ 3
+
+
+ 0
+ Deploy
+ Deploy
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+
+ false
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+ true
+ true
+ true
+
+ 2
+
+ TcpClient2
+ Qt4ProjectManager.Qt4RunConfiguration:C:/Users/25761/Desktop/tcpclient/TcpClient.pro
+ C:/Users/25761/Desktop/tcpclient/TcpClient.pro
+ false
+ true
+ true
+ false
+ true
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MinGW_64_bit-Debug
+
+ 1
+
+
+
+ ProjectExplorer.Project.Target.1
+
+ Desktop
+ Desktop Qt 6.2.3 MSVC2019 64bit
+ Desktop Qt 6.2.3 MSVC2019 64bit
+ qt.qt6.623.win64_msvc2019_64_kit
+ 0
+ 0
+ 0
+
+ 0
+ C:\Users\25761\Desktop\build-TcpClient-Desktop_Qt_6_2_3_MSVC2019_64bit-Debug
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MSVC2019_64bit-Debug
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+
+
+ C:\Users\25761\Desktop\build-TcpClient-Desktop_Qt_6_2_3_MSVC2019_64bit-Release
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MSVC2019_64bit-Release
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+
+
+ 0
+ C:\Users\25761\Desktop\build-TcpClient-Desktop_Qt_6_2_3_MSVC2019_64bit-Profile
+ C:/Users/25761/Desktop/build-TcpClient-Desktop_Qt_6_2_3_MSVC2019_64bit-Profile
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+ 0
+
+ 3
+
+
+ 0
+ Deploy
+ Deploy
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+
+ false
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+ true
+ true
+ true
+
+ 2
+
+ Qt4ProjectManager.Qt4RunConfiguration:C:/Users/25761/Desktop/TcpClient/TcpClient.pro
+ C:/Users/25761/Desktop/TcpClient/TcpClient.pro
+ false
+ true
+ true
+ false
+ true
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 2
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 22
+
+
+ Version
+ 22
+
+
diff --git a/datamanager.cpp b/datamanager.cpp
new file mode 100644
index 0000000..c87c393
--- /dev/null
+++ b/datamanager.cpp
@@ -0,0 +1,69 @@
+#include "datamanager.h"
+
+DataManager::DataManager(QObject *parent)
+ : QObject{parent}
+{
+ qDebug() << "进入DataManager的构造函数";
+ tcpclient = TCPClient::getInstance();
+ connect(tcpclient,&TCPClient::TCPClientConnected,this,&DataManager::TCPClientConnected);
+ connect(tcpclient,&TCPClient::TCPClientDisconnected,this,&DataManager::TCPClientDisconnected);
+ tcpclient->configAndrun();
+ tcpclient->setCallBack(recv_from_server);
+ protocol = Protocol::getInstance();
+
+}
+
+DataManager* DataManager::getInstance()
+{
+ static DataManager datamanager_instance;
+ return &datamanager_instance;
+}
+
+void DataManager::TCPClientConnected()
+{
+ connect_flag = true;
+ qDebug() << "emit connect_to_server successfully";
+ emit connect_to_server();
+}
+
+void DataManager::TCPClientDisconnected()
+{
+ connect_flag = false;
+ qDebug() << "emit disconnect_from_server successfully";
+ emit disconnect_from_server();
+}
+
+void DataManager::recv_from_server(QString &peerAddress, quint16 peerPort, QByteArray &data)
+{
+ //
+}
+
+void DataManager::Register(QString username,QString password)
+{
+
+}
+
+void DataManager::signin_request(QString username,QString password)
+{
+
+}
+
+void DataManager::send_text(QString text)
+{
+
+}
+
+void DataManager::send_file_to_all(QByteArray file)
+{
+
+}
+
+void DataManager::send_file_private(QByteArray file,QString name)
+{
+
+}
+
+void DataManager::account_cancellation(QString username)
+{
+
+}
diff --git a/datamanager.h b/datamanager.h
new file mode 100644
index 0000000..705156b
--- /dev/null
+++ b/datamanager.h
@@ -0,0 +1,48 @@
+#ifndef DATAMANAGER_H
+#define DATAMANAGER_H
+
+#include
+#include
+
+#include "protocol.h"
+#include "tcpclient.h"
+
+class DataManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataManager(QObject *parent = nullptr);
+ static void recv_from_server(QString &peerAddress,quint16 peerPort,QByteArray &data);
+ static DataManager* getInstance();
+
+private:
+ Protocol *protocol;
+ TCPClient *tcpclient;
+ QString username;
+ QString password;
+ bool connect_flag = false;
+
+signals:
+ void connect_to_server();
+ void disconnect_from_server();
+ void signin_response(bool result);
+ void signup_response(bool result);
+
+public slots:
+ /*******ui界面********/
+ void Register(QString username,QString password);
+ void signin_request(QString username,QString password);
+
+ /******MAINWIDGET*****/
+ void send_text(QString text);
+ void send_file_to_all(QByteArray file);
+ void send_file_private(QByteArray file,QString name);
+ void account_cancellation(QString username);
+
+ /******TCPClient******/
+ void TCPClientConnected();
+ void TCPClientDisconnected();
+
+};
+
+#endif // DATAMANAGER_H
diff --git a/imgs/background.png b/imgs/background.png
new file mode 100644
index 0000000..8d8a990
Binary files /dev/null and b/imgs/background.png differ
diff --git a/imgs/blue.png b/imgs/blue.png
new file mode 100644
index 0000000..1d75deb
Binary files /dev/null and b/imgs/blue.png differ
diff --git a/imgs/close.png b/imgs/close.png
new file mode 100644
index 0000000..6017c93
Binary files /dev/null and b/imgs/close.png differ
diff --git a/imgs/icon.png b/imgs/icon.png
new file mode 100644
index 0000000..9bf75cd
Binary files /dev/null and b/imgs/icon.png differ
diff --git a/imgs/imgs.qrc b/imgs/imgs.qrc
new file mode 100644
index 0000000..ff709f0
--- /dev/null
+++ b/imgs/imgs.qrc
@@ -0,0 +1,8 @@
+
+
+ background.png
+ blue.png
+ close.png
+ icon.png
+
+
diff --git a/login.cpp b/login.cpp
new file mode 100644
index 0000000..6b9f665
--- /dev/null
+++ b/login.cpp
@@ -0,0 +1,224 @@
+#include "login.h"
+#include "ui_login.h"
+
+Login::Login(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::Login)
+{
+ /**********ui_init**********/
+ ui->setupUi(this);
+ this->setWindowIcon(QIcon(":/icon.png"));
+ this->setWindowFlags(Qt::FramelessWindowHint); //无边框
+ this->setAttribute(Qt::WA_TranslucentBackground);
+ new_closebutton(ui->close_btn,":/close.png", QSize(30, 30));
+
+ /********datamanager********/
+ datamanager = DataManager::getInstance();
+ connect(datamanager,&DataManager::signin_response,this,&Login::signin_response);
+ connect(datamanager,&DataManager::signup_response,this,&Login::signup_response);
+ connect(datamanager,&DataManager::connect_to_server,this,&Login::connected);
+ connect(datamanager,&DataManager::disconnect_from_server,this,&Login::disconnected);
+ connect(this,&Login::signin_request,datamanager,&DataManager::signin_request);
+ connect(this,&Login::Register,datamanager,&DataManager::Register);
+
+}
+
+Login::~Login()
+{
+ delete ui;
+}
+
+void Login::paintEvent(QPaintEvent *event)
+{
+ //创建画家,指定绘图设备
+ // QPainter painter(this);
+ //创建QPixmap对象
+ // QPixmap pix;
+ //加载图片
+ // pix.load(":/sources/xxx.png");
+ //绘制背景图
+ // painter.drawPixmap(0,0,this->width(),this->height(),pix);
+
+ //绘制样式
+ // QBitmap bmp(this->size());
+ // bmp.fill();
+ // QPainter painter(&bmp);
+ // painter.setPen(Qt::NoPen);
+ // painter.setBrush(Qt::black);
+ // painter.setRenderHint(QPainter::Antialiasing);
+ // painter.drawRoundedRect(bmp.rect(), 6, 6);
+ // setMask(bmp);
+
+ QPixmap pix;
+ pix.load(":/background.png");
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
+
+ painter.setPen(Qt::transparent);
+ QRect rect = this->rect(); // rect为绘制大小
+ rect.setWidth(rect.width() - 1);
+ rect.setHeight(rect.height() - 1);
+ painter.drawRoundedRect(rect, 10, 10); // 10为圆角角度
+ painter.drawPixmap(rect, pix); //绘制背景图
+
+ // painter.setBrush(QBrush(QColor(255,245,225,240)));
+ // painter.setPen(Qt::transparent);
+ //也可用QPainterPath 绘制代替 painter.drawRoundedRect(rect, 15, 15);
+ // QPainterPath painterPath;
+ // painterPath.addRoundedRect(rect, 15, 15);//15为圆角角度
+ // painter.drawPath(painterPath);
+
+ //设置阴影
+ QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
+ shadow->setOffset(0, 0); //设置阴影距离
+ shadow->setColor(QColor("#87CEFA")); //设置阴影颜色
+ shadow->setBlurRadius(10); //设置阴影圆角
+ ui->btn_signin->setGraphicsEffect(shadow);
+ ui->btn_signup->setGraphicsEffect(shadow);
+}
+
+void Login::new_closebutton(QPushButton* btn, QString position,QSize size)
+{
+ QPixmap pixmap;
+ pixmap.load(position);
+ btn->setIconSize(size);
+ btn->setStyleSheet("QPushButton{border-width: 1px;border-style: solid;border-radius:15px;background-color: rgb(64, 145, 252);}"
+ "QPushButton:hover{background-color:#999999;}");
+ //设置图标
+ btn->setIcon(pixmap);
+}
+
+void Login::mousePressEvent(QMouseEvent *event)
+{
+ if (event->buttons() == Qt::LeftButton)
+ {
+ point = event->pos();
+ }
+}
+
+void Login::mouseMoveEvent(QMouseEvent *event)
+{
+ if (event->buttons() == Qt::LeftButton)
+ {
+ //当窗口最大化或最小化时也不进行触发
+ if (Login::isMaximized() || Login::isMinimized())
+ {
+ return;
+ }
+ else
+ {
+ //当在按钮之类需要鼠标操作的地方不进行触发(防误触)
+ if (ui->btn_signin->underMouse() || ui->btn_signup->underMouse())
+ {
+ return;
+ }
+ else
+ {
+ Login::move(Login::mapToGlobal(event->pos() - point));
+ }
+ }
+ }
+ event->accept();
+}
+
+void Login::on_btn_signin_clicked()
+{
+ if(connect_flag == true)
+ {
+ user = ui->lineEdit_username->text();
+ passwd = ui->lineEdit_password->text();
+ if(user.isEmpty() || passwd.isEmpty())
+ {
+ QMessageBox::warning(this,tr("错误"),tr("用户名和密码不能为空!"));
+ }
+ emit signin_request(user,passwd);
+ }
+ else
+ {
+ QMessageBox::warning(this, "登录失败", "尚未连接服务器!");
+ return;
+ }
+}
+
+void Login::on_btn_signup_clicked()
+{
+ signup = new Signup();
+ connect(signup,&Signup::show_login_ui,this,&Login::show_login_ui);
+ connect(signup,&Signup::Register,this,&Login::slot_Register);
+ this->hide();
+ signup->show();
+}
+
+void Login::on_close_btn_clicked()
+{
+ this->close();
+}
+
+void Login::show_login_ui()
+{
+ this->show();
+}
+
+//等待服务器验证登陆数据
+void Login::signin_response(bool result)
+{
+ if(result == true)
+ {
+ mainwidget = new MainWidget(user);
+ connect(mainwidget,&MainWidget::send_text,datamanager,&DataManager::send_text);
+ connect(mainwidget,&MainWidget::send_file_private,datamanager,&DataManager::send_file_private);
+ connect(mainwidget,&MainWidget::send_file_to_all,datamanager,&DataManager::send_file_to_all);
+ connect(mainwidget,&MainWidget::account_cancellation,datamanager,&DataManager::account_cancellation);
+ connect(mainwidget,&MainWidget::exit_client,this,&Login::exit_client);
+ this->hide();
+ mainwidget->show();
+ }
+ else
+ {
+ QMessageBox::warning(this,tr("登录失败"),tr("用户名或密码错误!"));
+ }
+}
+
+void Login::slot_Register(QString username,QString password)
+{
+ if(connect_flag == false)
+ {
+ QMessageBox::warning(signup, "注册失败", "尚未连接服务器!请连接服务器后重试");
+ return;
+ }
+ emit Register(username,password);
+}
+
+//等待服务器注册数据
+void Login::signup_response(bool result)
+{
+ if(result == true)
+ {
+ QString information = QString("请妥善保存您的用户名和密码!");
+ QMessageBox::information(signup,tr("注册成功"),information);
+ }
+ else
+ {
+ QMessageBox::warning(signup,tr("错误"),tr("注册失败,请重试!"));
+ }
+}
+
+//连接上服务器
+void Login::connected()
+{
+ qDebug() << "connect to server";
+ connect_flag = true;
+}
+
+//未连上服务器或服务器断开
+void Login::disconnected()
+{
+ qDebug() << "disconnect from server";
+ connect_flag = false;
+}
+
+void Login::exit_client()
+{
+ this->close();
+}
diff --git a/login.h b/login.h
new file mode 100644
index 0000000..d07f473
--- /dev/null
+++ b/login.h
@@ -0,0 +1,65 @@
+#ifndef LOGIN_H
+#define LOGIN_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mainwidget.h"
+#include "signup.h"
+#include "datamanager.h"
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class Login; }
+QT_END_NAMESPACE
+
+class Login : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit Login(QWidget *parent = nullptr);
+ ~Login();
+ void paintEvent(QPaintEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void new_closebutton(QPushButton* btn, QString position,QSize size);
+
+signals:
+ void signin_request(QString username,QString password);
+ void Register(QString username,QString password);
+
+private slots:
+ void on_btn_signin_clicked();
+ void on_btn_signup_clicked();
+ void on_close_btn_clicked();
+
+ void signin_response(bool result);
+ void signup_response(bool result);
+ void show_login_ui();
+ void slot_Register(QString username,QString password);
+ void connected();
+ void disconnected();
+ void exit_client();
+
+private:
+ Ui::Login *ui;
+ QPoint point;
+ QString user,passwd;
+ static Login login_instance;
+ Login *login;
+ Signup *signup;
+ MainWidget *mainwidget;
+ DataManager *datamanager;
+ bool connect_flag = false;
+
+};
+
+#endif // LOGIN_H
diff --git a/login.ui b/login.ui
new file mode 100644
index 0000000..02b9b22
--- /dev/null
+++ b/login.ui
@@ -0,0 +1,162 @@
+
+
+ Login
+
+
+
+ 0
+ 0
+ 946
+ 665
+
+
+
+ MainWindow
+
+
+
+
+
+ 480
+ 410
+ 71
+ 40
+
+
+
+
+ 50
+ 40
+
+
+
+ background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0,
+stop:1 rgba(64, 145, 252, 255),
+stop:0 rgba(220, 255, 255, 255));
+color: rgb(255, 255, 255);
+
+border:0px groove gray;border-radius:
+7px;padding:2px 4px;
+font: 14pt "Candara";
+
+
+ Sign in
+
+
+
+
+
+ 450
+ 270
+ 289
+ 45
+
+
+
+
+ 0
+ 45
+
+
+
+ background-color: rgb(247, 247, 247);
+border:1px groove gray;border-radius:
+7px;padding:2px 4px;
+font: 12pt "Candara";
+
+
+ Please input your ID
+
+
+
+
+
+ 630
+ 410
+ 79
+ 40
+
+
+
+
+ 50
+ 40
+
+
+
+ background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0,
+stop:1 rgba(64, 145, 252, 255),
+stop:0 rgba(220, 255, 255, 255));
+color: rgb(255, 255, 255);
+
+border:0px groove gray;border-radius:
+7px;padding:2px 4px;
+font: 14pt "Candara";
+
+
+ Sign up
+
+
+
+
+
+ 820
+ 140
+ 31
+ 31
+
+
+
+
+
+
+
+
+
+ 450
+ 330
+ 289
+ 45
+
+
+
+
+ 0
+ 45
+
+
+
+ background-color: rgb(247, 247, 247);
+border:1px groove gray;border-radius:
+7px;padding:2px 4px;
+font: 12pt "Candara";
+
+
+ QLineEdit::Password
+
+
+ Please input your password
+
+
+
+
+
+ 500
+ 200
+ 191
+ 51
+
+
+
+ font: 87 20pt "Arial Black";
+background:transparent;
+
+
+ Login Now
+
+
+
+
+
+
+
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..05aeac6
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,11 @@
+#include "login.h"
+
+#include
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ Login w;
+ w.show();
+ return a.exec();
+}
diff --git a/mainwidget.cpp b/mainwidget.cpp
new file mode 100644
index 0000000..92c88b1
--- /dev/null
+++ b/mainwidget.cpp
@@ -0,0 +1,232 @@
+#include "mainwidget.h"
+#include "ui_mainwidget.h"
+
+MainWidget::MainWidget(QString username,QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::MainWidget)
+{
+ ui->setupUi(this);
+ this->setWindowIcon(QIcon(":/icon.png"));
+ this->setWindowTitle("TCP聊天室");
+ ui->name_list->setEditTriggers(QAbstractItemView::NoEditTriggers); //不允许编辑
+ ui->name_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ ui->name_list->verticalScrollBar()->setStyleSheet("QScrollBar{width:16px;}");
+ ui->textEdit->setReadOnly(true);
+ ui->send_btn->setFocus();
+ ui->send_btn->setDefault(true);
+ ui->msg_edit->installEventFilter(this);//设置完后自动调用其eventFilter函数
+ this->username = username;
+}
+
+MainWidget::~MainWidget()
+{
+ delete ui;
+}
+
+void MainWidget::on_send_text_clicked()
+{
+ QString homePath = QDir::homePath();
+ QString filePath = QFileDialog::getOpenFileName(this, tr("Open a file"), homePath, tr("All files (*.*)"), NULL, QFileDialog::DontResolveSymlinks);
+
+ QString filename = filePath.section("/", -1);
+
+ if (filename.isEmpty())
+ return;
+
+ QMessageBox::StandardButton reply;
+ reply = QMessageBox::question(this, "发送文件", tr("Do you want to send \"%1\"?").arg(filename));
+
+ if (reply == QMessageBox::No)
+ return;
+ else
+ {
+ QString currentTime = QTime::currentTime().toString("H:mm A");
+ ui->textEdit->append("" + username + " [" + currentTime + "] send a file \"" + filename + "\"");
+
+ QString name = ui->msg_edit->text();
+ if(name.isEmpty()) //群发
+ {
+ this->sendFile(filePath,filename);
+ }
+ else //私发文件
+ {
+ this->sendFile(filePath,filename,name);
+ }
+ QProgressDialog *progressDlg = new QProgressDialog(this);
+ progressDlg->setWindowModality(Qt::WindowModal);
+ progressDlg->setMinimumDuration(0);
+ progressDlg->setAttribute(Qt::WA_DeleteOnClose, true);
+ progressDlg->setWindowTitle(tr("上传文件"));
+ progressDlg->setLabelText(tr("正在上传......"));
+ progressDlg->setCancelButtonText(tr("取消"));
+ progressDlg->setRange(0, 8000);
+ for (int i = 1; i < 8000; i++)
+ {
+ progressDlg->setValue(i);
+ if (progressDlg->wasCanceled())
+ {
+ break;
+ }
+ }
+ progressDlg->close();
+ }
+}
+
+void MainWidget::on_save_btn_clicked()
+{
+ QFile file("memory.txt");
+ if (file.exists()) //文件存在
+ {
+ QMessageBox::StandardButton reply;
+ reply = QMessageBox::question(this, "提示", tr("是否覆盖之前的聊天记录?"));
+ if (reply == QMessageBox::No)
+ {
+ if (file.open(QIODevice::WriteOnly | QIODevice::Append))
+ {
+ QTextStream stream(&file);
+ //转换为字符串
+ QString str = ui->textEdit->toPlainText();
+ str = "\n\n" + str;
+ //写入文本流
+ stream << str;
+ //关闭文件
+ file.close();
+ }
+ }
+ else
+ {
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text))
+ {
+ QTextStream stream(&file);
+ //转换为字符串
+ QString str = ui->textEdit->toPlainText();
+ //写入文本流
+ stream << str;
+ //关闭文件
+ file.close();
+ }
+ }
+ }
+
+ else
+ {
+ QMessageBox::warning(this, "提示", tr("打开文件失败,已为您自动创建文件!"));
+ file.open(QIODevice::WriteOnly | QIODevice::Append);
+ }
+}
+
+void MainWidget::on_send_btn_clicked()
+{
+ QString text;
+ text = ui->msg_edit->text();
+ if(text.isEmpty())
+ {
+ QMessageBox::warning(this, "发送失败", "输入不能为空!");
+ return;
+ }
+ ui->msg_edit->clear();
+ QString currentTime = QTime::currentTime().toString("H:m A");
+ ui->textEdit->append("" + username + " [" + currentTime + "] : " + text + "");
+ emit send_text(text);
+}
+
+
+void MainWidget::on_name_list_itemDoubleClicked(QListWidgetItem *item)
+{
+ QString client_name = ui->name_list->currentItem()->text();
+ QString a = "@";
+ a = a + client_name + " ";
+ ui->msg_edit->clear();
+ ui->msg_edit->setText(a);
+}
+
+
+void MainWidget::on_exit_btn_clicked()
+{
+ QMessageBox::StandardButton response;
+ response = QMessageBox::question(this, "退出", tr("是否退出软件?"));
+
+ if(response == QMessageBox::Yes)
+ {
+ emit exit_client();
+ this->close();
+ }
+ else
+ {
+ return;
+ }
+}
+
+
+void MainWidget::on_stop_clicked()
+{
+ QMessageBox::StandardButton response;
+ response = QMessageBox::question(this, "注销", tr("是否退出软件并注销账户?"));
+
+ if(response == QMessageBox::Yes)
+ {
+ emit exit_client();
+ emit account_cancellation(username);
+ this->close();
+ }
+ else
+ {
+ return;
+ }
+}
+
+void MainWidget::sendFile(QString filePath,QString filename,QString name)
+{
+ //通过fileTcpSocket发送文件
+
+ //发送的数据存入block中
+ QByteArray block;
+ QFile file(filePath);
+ //打开文件,定义错误提醒
+ if(!file.open(QIODevice::ReadOnly)){
+ QMessageBox::warning(this,"","无法打开文件!");
+ return;
+ }
+ //打开文件流,以写的方式打开
+ QDataStream out(&block,QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_5_8);
+ QString command = filename+"\n";
+ out << command;
+ //将数据读取到QByteArray
+ QByteArray dataOfFile = file.readAll();
+ //关闭文件
+ file.close();
+ //放入block
+ block.append(dataOfFile);
+
+ if(name.isEmpty()) //群发文件
+ {
+ emit send_file_to_all(block);
+ }
+
+ else //私发文件
+ {
+ emit send_file_private(block,name);
+ }
+}
+
+bool MainWidget::eventFilter(QObject *target, QEvent *event)
+{
+ if(target == ui->msg_edit) //可替换
+ {
+ if(event->type() == QEvent::KeyPress)//回车键
+ {
+ QKeyEvent *k = static_cast(event);
+
+ if(k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter)
+ {
+ on_send_btn_clicked(); //替换为需要响应的函数事件,以这里的按钮为例
+ return true;
+ }
+ }
+ }
+ return QWidget::eventFilter(target,event);
+}
+
+
+
diff --git a/mainwidget.h b/mainwidget.h
new file mode 100644
index 0000000..50be97c
--- /dev/null
+++ b/mainwidget.h
@@ -0,0 +1,54 @@
+#ifndef MAINWIDGET_H
+#define MAINWIDGET_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Ui {
+class MainWidget;
+}
+
+class MainWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit MainWidget(QString username,QWidget *parent = nullptr);
+ ~MainWidget();
+ void sendFile(QString filePath,QString filename,QString name = "");
+ bool eventFilter(QObject *target, QEvent *event);
+
+signals:
+ void send_text(QString text);
+ void send_file_to_all(QByteArray file);
+ void send_file_private(QByteArray file,QString name);
+ void exit_client();
+ void account_cancellation(QString username);
+
+private slots:
+ void on_send_text_clicked();
+
+ void on_save_btn_clicked();
+
+ void on_send_btn_clicked();
+
+ void on_name_list_itemDoubleClicked(QListWidgetItem *item);
+
+ void on_exit_btn_clicked();
+
+ void on_stop_clicked();
+
+private:
+ Ui::MainWidget *ui;
+ QString username;
+};
+
+#endif // MAINWIDGET_H
diff --git a/mainwidget.ui b/mainwidget.ui
new file mode 100644
index 0000000..ae4d1c9
--- /dev/null
+++ b/mainwidget.ui
@@ -0,0 +1,231 @@
+
+
+ MainWidget
+
+
+
+ 0
+ 0
+ 798
+ 587
+
+
+
+ Form
+
+
+
+
+ 50
+ 510
+ 401
+ 31
+
+
+
+ -
+
+
+ 发送文件
+
+
+
+ -
+
+
+ 保存聊天记录
+
+
+
+
+
+
+
+
+ 520
+ 510
+ 211
+ 31
+
+
+
+ -
+
+
+ 退出聊天
+
+
+
+ -
+
+
+ 注销用户
+
+
+
+
+
+
+
+
+ 50
+ 30
+ 401
+ 421
+
+
+
+
+
+
+ 520
+ 30
+ 211
+ 441
+
+
+
+ -
+
+
+ font: 12pt "Arial Black";
+
+
+ 在线用户列表
+
+
+
+ -
+
+
+ QListWidget { outline: none; border:1px solid white; color: #696969;}
+ QListWidget::Item { width: 60px; height: 40px; }
+ QListWidget::Item:hover { background: #FFA500; color: white; }
+ QListWidget::item:selected { background: #FFC0CB; color: #DC143C; }
+ QListWidget::item:selected:!active { background: blue; }
+
+QScrollBar:vertical
+{
+ width:8px;
+ background:rgba(0,0,0,0%);
+ margin:0px,0px,0px,0px;
+ padding-top:16px;
+ padding-bottom:16px;
+}
+QScrollBar::handle:vertical
+{
+ width:8px;
+ background:rgba(0,0,0,25%);
+ border-radius:4px;
+ min-height:20;
+}
+QScrollBar::handle:vertical:hover
+{
+ width:8px;
+ background:rgba(0,0,0,50%);
+ border-radius:4px;
+ min-height:20;
+}
+/*
+QScrollBar::add-line:vertical
+{
+ height:9px;width:8px;
+ subcontrol-position:bottom;
+}
+QScrollBar::sub-line:vertical
+{
+ height:9px;width:8px;
+ subcontrol-position:top;
+}
+QScrollBar::add-line:vertical:hover
+{
+ height:9px;width:8px;
+ subcontrol-position:bottom;
+}
+QScrollBar::sub-line:vertical:hover
+{
+ height:9px;width:8px;
+ subcontrol-position:top;
+}
+
+QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical
+{
+ background:rgba(0,0,0,10%);
+ border-radius:4px;
+}*/
+
+
-
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+ -
+
+ 新建项目
+
+
+
+
+
+
+
+
+
+ 50
+ 460
+ 401
+ 31
+
+
+
+ -
+
+
+ -
+
+
+ 发送
+
+
+
+
+
+
+
+
+
diff --git a/protocol.cpp b/protocol.cpp
new file mode 100644
index 0000000..98db9b4
--- /dev/null
+++ b/protocol.cpp
@@ -0,0 +1,152 @@
+#include "protocol.h"
+#include
+#include
+
+Protocol Protocol::protocol_instance;
+Protocol::Protocol(QObject *parent)
+ : QObject{parent}
+{
+
+}
+
+Protocol::~Protocol()
+{
+
+}
+
+Protocol* Protocol::getInstance()
+{
+ return &protocol_instance;
+}
+
+QByteArray Protocol::data_builder(QList &args)
+{
+ QJsonObject data;
+ switch(args[0].get_data_types())
+ {
+ case MESSAGE:
+ {
+ if (args.length()==2)
+ {
+ data.insert("type","message");
+ data.insert("data",args[1].get_string());
+ }
+ else if (args.length()==3)
+ {
+ data.insert("type","message");
+ data.insert("to_user",args[1].get_string());
+ data.insert("data",args[2].get_string());
+ }
+ break;
+ }
+ case FILE:
+ {
+ data.insert("type","file");
+ data.insert("name",args[1].get_string());
+ data.insert("data",args[2].get_string());
+ break;
+ }
+ case REQUEST:
+ {
+ data.insert("type","request");
+ data.insert("action",args[1].get_string());
+ QList content = args[2].get_list();
+ QJsonObject json_content;
+ for (int i=0; i users = args[2].get_list();
+ QJsonArray json_users;
+ for (auto &user:users)
+ json_users.append(user);
+ data.insert("users",json_users);
+ break;
+ }
+ case RESPONSE:
+ {
+ data.insert("type","response");
+ data.insert("action",args[1].get_string());
+ QList content = args[2].get_list();
+ QJsonObject json_content;
+ for (int i=0; i Protocol::data_parser(QByteArray data)
+{
+ QJsonDocument json_data = QJsonDocument::fromJson(data);
+ if (json_data["type"] == "message")
+ return qMakePair(MESSAGE,json_data.object());
+ else if (json_data["type"] == "file")
+ return qMakePair(FILE,json_data.object());
+ else if (json_data["type"] == "request")
+ return qMakePair(REQUEST,json_data.object());
+ else if (json_data["type"] == "online_users")
+ return qMakePair(ONLINEUSERS,json_data.object());
+ else if (json_data["type"] == "response")
+ return qMakePair(RESPONSE,json_data.object());
+ else
+ return qMakePair(RESPONSE,json_data.object());
+}
+
+QByteArray Protocol::XOR_En_Decrypt(QString src)
+{
+ QByteArray result;
+ for(auto &i:src)
+ result.append(i.toLatin1() ^ cipher_word);
+ return result;
+}
+
+QByteArray Protocol::Upper_Lower_En_Decrypt(QString src)
+{
+ QByteArray result;
+ for(auto &i:src)
+ {
+ if(i.isUpper())
+ {
+ QChar word = i.toLower();
+ result.append(word.toLatin1());
+ }
+ else if (i.isLower())
+ {
+ QChar word = i.toUpper();
+ result.append(word.toLatin1());
+ }
+ else
+ result.append(i.toLatin1());
+ }
+ return result;
+}
+
+QByteArray Protocol::data_encrypt(QByteArray src)
+{
+ QByteArray en_base64 = src.toBase64();
+ QByteArray result = Upper_Lower_En_Decrypt(en_base64);
+ return XOR_En_Decrypt(result);
+}
+
+QByteArray Protocol::data_decrypt(QByteArray src)
+{
+ QByteArray result = XOR_En_Decrypt(src);
+ result = Upper_Lower_En_Decrypt(result);
+ return QByteArray::fromBase64(result);
+}
+
+void Protocol::set_data_cipher_word(char word)
+{
+ cipher_word = word;
+}
diff --git a/protocol.h b/protocol.h
new file mode 100644
index 0000000..8181b40
--- /dev/null
+++ b/protocol.h
@@ -0,0 +1,59 @@
+#ifndef PROTOCOL_H
+#define PROTOCOL_H
+
+#include
+#include
+
+class Protocol : public QObject
+{
+ Q_OBJECT
+public:
+ static Protocol* getInstance();
+ template
+ QByteArray data_maker(Type type, Args ...args)
+ {
+ QList args_list;
+ args_list.append(any_types(type));
+ (void)std::initializer_list {(args_list.append(any_types(args)),0)...};
+ return data_builder(args_list);
+ };
+ enum data_types {MESSAGE,FILE,REQUEST,ONLINEUSERS,RESPONSE};
+ QPair data_parser(QByteArray data);
+ QByteArray data_encrypt(QByteArray src);
+ void set_data_cipher_word(char word);
+ QByteArray data_decrypt(QByteArray src);
+private:
+ char cipher_word = 'G';
+ struct any_types {
+ enum type {String, Bool, Int, Data_types, List};
+ any_types(int e) { m_data.INT = e; m_type = Int;}
+ any_types(QString e) { m_data.STRING = e; m_type = String;}
+ any_types(QList e) { m_data.LIST = e; m_type = List;}
+ any_types(bool e) { m_data.BOOL = e; m_type = Bool;}
+ any_types(data_types e) { m_data.DATA_TYPES = e; m_type = Data_types;}
+ type get_type() const { return m_type; }
+ int get_int() const { return m_data.INT; }
+ bool get_bool() const { return m_data.BOOL; }
+ data_types get_data_types() const { return m_data.DATA_TYPES; }
+ QString get_string() const { return m_data.STRING; }
+ QList get_list() const { return m_data.LIST; }
+ private:
+ type m_type;
+ struct {
+ int INT;
+ bool BOOL;
+ QString STRING;
+ QList LIST;
+ data_types DATA_TYPES;
+ } m_data;
+ };
+ static Protocol protocol_instance;
+ explicit Protocol(QObject *parent = nullptr);
+ ~Protocol();
+ QByteArray data_builder(QList &args);
+ QByteArray XOR_En_Decrypt(QString src);
+ QByteArray Upper_Lower_En_Decrypt(QString src);
+signals:
+
+};
+#endif // PROTOCOL_H
diff --git a/signup.cpp b/signup.cpp
new file mode 100644
index 0000000..516da3f
--- /dev/null
+++ b/signup.cpp
@@ -0,0 +1,103 @@
+#include "signup.h"
+#include "ui_signup.h"
+
+Signup::Signup(QWidget *parent) : QWidget(parent),
+ ui(new Ui::Signup)
+{
+ ui->setupUi(this);
+ QPixmap *pix = new QPixmap(":/blue.png");
+ QSize sz = ui->label_image->size();
+ ui->label_image->setPixmap(pix->scaled(sz));
+
+ this->setWindowIcon(QIcon(":/icon.png"));
+ this->setWindowFlags(Qt::FramelessWindowHint); //无边框
+
+ //设置阴影
+ QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
+ shadow->setOffset(-3, 0);
+ shadow->setColor(QColor("#888888"));
+ shadow->setBlurRadius(30);
+ ui->label_image->setGraphicsEffect(shadow);
+}
+
+Signup::~Signup()
+{
+ delete ui;
+}
+
+//返回登录按钮
+void Signup::on_btn_return_clicked()
+{
+ this->close();
+ emit show_login_ui();
+}
+
+//注册按钮
+void Signup::on_btn_sure_clicked()
+{
+ QString username = ui->lineEdit_username->text();
+ QString password = ui->lineEdit_passwd->text();
+ QString surepass = ui->lineEdit_surepasswd->text();
+ if (username.isEmpty() || password.isEmpty() || surepass.isEmpty())
+ {
+ QMessageBox::warning(this, "注册失败", "输入不能为空!");
+ }
+
+ else
+ {
+ if (password == surepass)
+ {
+ emit Register(username,password);
+ }
+ else
+ {
+ QMessageBox::information(this, "用户注册", "两次密码输入不一致!");
+ }
+ }
+}
+
+void Signup::paintEvent(QPaintEvent *event)
+{
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
+
+ painter.setPen(Qt::transparent);
+ QRect rect = this->rect(); // rect为绘制大小
+ rect.setWidth(rect.width() - 1);
+ rect.setHeight(rect.height() - 1);
+ painter.drawRoundedRect(rect, 10, 10); // 10为圆角角度
+}
+
+void Signup::mousePressEvent(QMouseEvent *event)
+{
+ if (event->buttons() == Qt::LeftButton)
+ {
+ point = event->pos();
+ }
+}
+
+void Signup::mouseMoveEvent(QMouseEvent *event)
+{
+ if (event->buttons() == Qt::LeftButton)
+ {
+ //当窗口最大化或最小化时也不进行触发
+ if (Signup::isMaximized() || Signup::isMinimized())
+ {
+ return;
+ }
+ else
+ {
+ //当在按钮之类需要鼠标操作的地方不进行触发(防误触)
+ if (ui->btn_sure->underMouse() || ui->btn_return->underMouse())
+ {
+ return;
+ }
+ else
+ {
+ Signup::move(Signup::mapToGlobal(event->pos() - point)); //移动
+ }
+ }
+ }
+ event->accept();
+}
+
diff --git a/signup.h b/signup.h
new file mode 100644
index 0000000..d5d8147
--- /dev/null
+++ b/signup.h
@@ -0,0 +1,44 @@
+#ifndef SIGNUP_H
+#define SIGNUP_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Ui {
+class Signup;
+}
+
+class Signup : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Signup(QWidget *parent = nullptr);
+ ~Signup();
+ void paintEvent(QPaintEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+
+signals:
+ void Register(QString username,QString password);
+ void show_login_ui();
+
+private slots:
+ void on_btn_sure_clicked();
+ void on_btn_return_clicked();
+
+private:
+ Ui::Signup *ui;
+ QPoint point;
+};
+
+#endif // SIGNUP_H
diff --git a/signup.ui b/signup.ui
new file mode 100644
index 0000000..1e3d913
--- /dev/null
+++ b/signup.ui
@@ -0,0 +1,211 @@
+
+
+ Signup
+
+
+
+ 0
+ 0
+ 780
+ 520
+
+
+
+ Form
+
+
+
+
+ 390
+ -10
+ 391
+ 531
+
+
+
+ TextLabel
+
+
+
+
+
+ 60
+ 150
+ 271
+ 344
+
+
+
+ -
+
+
+ font: 10.5pt "Arial";
+
+
+ Username
+
+
+
+ -
+
+
+
+ 0
+ 40
+
+
+
+ font: 12pt "Arial";
+
+
+
+ -
+
+
+ font: 11pt "Arial";
+
+
+ Password
+
+
+
+ -
+
+
+
+ 0
+ 40
+
+
+
+ font: 12pt "Arial";
+
+
+
+ -
+
+
+ font: 10.5pt "Arial";
+
+
+ Ensure your password:
+
+
+
+ -
+
+
+
+ 0
+ 40
+
+
+
+ font: 12pt "Arial";
+
+
+
+ -
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 40
+
+
+
+ background-color: rgb(29, 123, 255);
+color: rgb(255, 255, 255);
+font: 26 10pt "Bahnschrift Light";
+
+
+ Sure
+
+
+
+ -
+
+
+
+ 0
+ 40
+
+
+
+ background-color: rgb(29, 123, 255);
+color: rgb(255, 255, 255);
+font: 26 10pt "Bahnschrift Light";
+
+
+ Return login
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+ 60
+ 80
+ 301
+ 51
+
+
+
+ font: 87 20pt "Arial Black";
+
+
+ Welcome to us!
+
+
+
+
+
+ 60
+ 50
+ 161
+ 31
+
+
+
+ font: 87 20pt "Arial Black";
+
+
+ Hello
+
+
+
+
+
+
diff --git a/tcpclient.cpp b/tcpclient.cpp
new file mode 100644
index 0000000..334fcf0
--- /dev/null
+++ b/tcpclient.cpp
@@ -0,0 +1,101 @@
+#include "tcpclient.h"
+#include
+#include
+#include
+
+using namespace std;
+TCPClient TCPClient::tcpclient_instance;
+QTcpSocket TCPClient::socket;
+
+TCPClient::TCPClient(QObject *parent)
+ : QObject{parent}
+{
+
+}
+
+TCPClient::~TCPClient()
+{
+
+}
+
+TCPClient* TCPClient::getInstance()
+{
+ return &tcpclient_instance;
+}
+
+void TCPClient::configAndrun()
+{
+ qDebug() << "进入configandrun";
+ socket.setSocketOption(QAbstractSocket::KeepAliveOption,1);
+ socket.connectToHost(server_ip, server_port);
+ connect(&socket,&QTcpSocket::connected,this,&TCPClient::connected);
+ connect(&socket,&QTcpSocket::disconnected,this,&TCPClient::disconnected);
+ connect(&socket,&QTcpSocket::readyRead,this,&TCPClient::readSocket);
+ qDebug() << "连接到服务器";
+}
+
+void TCPClient::sendToserver(QByteArray &data)
+{
+ if (socket.isOpen())
+ {
+ socket.write(data);
+ socket.waitForBytesWritten(2000);
+ }
+}
+
+void TCPClient::setServer(QString IP, qint16 port)
+{
+ server_ip = IP;
+ server_port = port;
+}
+
+void TCPClient::connected()
+{
+ qDebug() << "1";
+ emit TCPClientConnected();
+ qDebug() << "emit TCPClientConnected successfully";
+ QString addr_t = socket.peerAddress().toString();
+ QByteArray addr = addr_t.toLocal8Bit();
+ printf("Connected to server at %.*s:%d.\n",addr.size(),addr.data(),socket.peerPort());
+}
+
+void TCPClient::disconnected()
+{
+ emit TCPClientDisconnected();
+ qDebug() << "emit TCPClientDisconnected successfully";
+ printf("Disconnected from server.\n");
+}
+
+void TCPClient::readSocket()
+{
+ QByteArray recv;
+ while(socket.bytesAvailable())//循环接收
+ {
+ recv += socket.readAll();
+ if (!socket.waitForReadyRead(20))//超时停止接收
+ {
+ /*QString error = sock->errorString();
+ string error_t = error.toStdString();
+ log_w("error:%d: %.*s", sock->error(),error_t.length(), error_t.data());*/
+ break;
+ }
+ }
+ QString ip = socket.peerAddress().toString();
+ string ip_t = ip.toStdString();
+ printf("TCPC: Recvd from %.*s:%d\n", ip_t.length(), ip_t.data(), socket.peerPort());
+ printf("TCPC Message:%.*s\n",recv.size(),(char *)recv.data());
+ if (_callback != nullptr)
+ _callback(ip, socket.peerPort(),recv);
+}
+
+void TCPClient::setCallBack(void (*callback)(QString &mac, quint16 port, QByteArray &data))
+{
+ _callback = callback;
+}
+
+void TCPClient::_sleep(int msec)
+{
+ QTime dieTime = QTime::currentTime().addMSecs(msec);
+ while( QTime::currentTime() < dieTime )
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
+}
diff --git a/tcpclient.h b/tcpclient.h
new file mode 100644
index 0000000..9891567
--- /dev/null
+++ b/tcpclient.h
@@ -0,0 +1,37 @@
+#ifndef TCPCLIENT_H
+#define TCPCLIENT_H
+
+#include
+#include
+#include
+
+class TCPClient : public QObject
+{
+ Q_OBJECT
+public:
+ static TCPClient* getInstance();
+ static void sendToserver(QByteArray &data);
+ void configAndrun();
+ void setCallBack(void (*callback)(QString &ip, quint16 port, QByteArray &data));
+ void setServer(QString IP, qint16 port);
+private slots:
+ void readSocket();
+ void connected();
+ void disconnected();
+private:
+ explicit TCPClient(QObject *parent = nullptr);
+ ~TCPClient();
+ static void _sleep(int msec);
+ static QTcpSocket socket;
+ static TCPClient tcpclient_instance;
+ QString server_ip = "127.0.0.1";
+ qint16 server_port = 7890;
+ bool has_found = false;
+ void (*_callback) (QString &ip, quint16 port, QByteArray &data)=nullptr;
+signals:
+ void TCPClientConnected();
+ void TCPClientDisconnected();
+
+};
+
+#endif // TCPCLIENT_H