├── README.md
├── resource
├── 008 Rainy Ashville.png
├── 050 Snow Again.png
├── 051 February Ink.png
├── 094 Cloudy Apple - trans.png
├── 094 Cloudy Apple.png
├── addfriends.jpg
├── andan.jpg
├── andan_touming.jpg
├── back.png
├── suliao.png
├── suliao_avator.png
├── suliao_avator_normal.jpg
├── suliao_big.png
├── suliao_normal.png
└── tubiao.qrc
├── server
└── server
│ ├── clienthandler.cpp
│ ├── clienthandler.h
│ ├── connectionpool.cpp
│ ├── connectionpool.h
│ ├── main.cpp
│ ├── server.cpp
│ ├── server.h
│ ├── server.pro
│ ├── server.pro.user
│ ├── server.ui
│ └── server_zh_CN.ts
└── user
└── user
├── addfriends.cpp
├── addfriends.h
├── addfriends.ui
├── autocleartextedit.cpp
├── autocleartextedit.h
├── changeinformation.cpp
├── changeinformation.h
├── changeinformation.ui
├── changepassword.cpp
├── changepassword.h
├── changepassword.ui
├── choicedialog.cpp
├── choicedialog.h
├── choicedialog.ui
├── cutavator.cpp
├── cutavator.h
├── cutavator.ui
├── dialog.cpp
├── dialog.h
├── dialog.ui
├── findpassword.cpp
├── findpassword.h
├── findpassword.ui
├── friendmessage.cpp
├── friendmessage.h
├── friendmessage.ui
├── login.cpp
├── login.h
├── login.ui
├── logout.cpp
├── logout.h
├── logout.ui
├── main.cpp
├── mainwindow-else.cpp
├── mainwindow-else.h
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── registerwindow.cpp
├── registerwindow.h
├── registerwindow.ui
├── user.pro
├── user.pro.user
└── user_zh_CN.ts
/README.md:
--------------------------------------------------------------------------------
1 | 这是博主学习几个月后做的第一个项目 qt版本是6.7.2 之前没有开发经验 所以可能bug会比较多 我也会持续修改更新 代码也比较杂乱 好在注释加的比较多
2 | 大家有需要的可以重构一下 大家把login和mainwindow的tcpConnect函数的地址和端口号改为自己需要的就可以使用了
3 | 因为qt6没有自带mysql的驱动 所以数据库直接使用的sqlite 数据库代码也可以在文件中找到
4 |
--------------------------------------------------------------------------------
/resource/008 Rainy Ashville.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/008 Rainy Ashville.png
--------------------------------------------------------------------------------
/resource/050 Snow Again.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/050 Snow Again.png
--------------------------------------------------------------------------------
/resource/051 February Ink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/051 February Ink.png
--------------------------------------------------------------------------------
/resource/094 Cloudy Apple - trans.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/094 Cloudy Apple - trans.png
--------------------------------------------------------------------------------
/resource/094 Cloudy Apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/094 Cloudy Apple.png
--------------------------------------------------------------------------------
/resource/addfriends.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/addfriends.jpg
--------------------------------------------------------------------------------
/resource/andan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/andan.jpg
--------------------------------------------------------------------------------
/resource/andan_touming.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/andan_touming.jpg
--------------------------------------------------------------------------------
/resource/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/back.png
--------------------------------------------------------------------------------
/resource/suliao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/suliao.png
--------------------------------------------------------------------------------
/resource/suliao_avator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/suliao_avator.png
--------------------------------------------------------------------------------
/resource/suliao_avator_normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/suliao_avator_normal.jpg
--------------------------------------------------------------------------------
/resource/suliao_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/suliao_big.png
--------------------------------------------------------------------------------
/resource/suliao_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qiuyue0125/SULIAO/11f937e6d174f11f1528a3996052df3c8e522550/resource/suliao_normal.png
--------------------------------------------------------------------------------
/resource/tubiao.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | suliao.png
4 | suliao_avator.png
5 | suliao_avator_normal.jpg
6 | 008 Rainy Ashville.png
7 | 051 February Ink.png
8 | 050 Snow Again.png
9 | 094 Cloudy Apple.png
10 | addfriends.jpg
11 | andan.jpg
12 | andan_touming.jpg
13 | 094 Cloudy Apple - trans.png
14 | back.png
15 |
16 |
17 |
--------------------------------------------------------------------------------
/server/server/clienthandler.h:
--------------------------------------------------------------------------------
1 | #ifndef CLIENTHANDLER_H
2 | #define CLIENTHANDLER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "server.h"
26 | #include "connectionpool.h"
27 |
28 | class Server;
29 |
30 | class ClientHandler : public QThread//用来处理消息的类
31 | {
32 | Q_OBJECT
33 | public:
34 | ClientHandler(QTcpSocket *socket,ConnectionPool& pool,Server *srv);
35 | ~ClientHandler();
36 | void run() override;//启用事件循环
37 | bool databasesConnect();//连接数据库
38 | void addClient(const QString &account, ClientHandler *client);//将登录成功的用户增加到哈希存储
39 | void removeClient(const QString &account);//用户断开连接 删除对应的哈希存储
40 | ClientHandler* getClient(const QString &account);//获得某个账号对应的ClientHandler
41 |
42 | public slots:
43 | void onReadyRead();//读取用户发送的数据
44 | void onDisconnected();//有用户断联了
45 | void receiveMessage(const QJsonObject &json);//收到别的客户端发送的消息 然后转发
46 |
47 | public://接收到客户端发送的消息 然后回发
48 | QString pixmapToBase64(const QPixmap &pixmap);//图片转换成base64格式
49 | QPixmap base64ToPixmap(const QString &base64Str);//将base64转换为图片
50 | void dealLogin(const QJsonObject &json);//处理登录请求
51 | void dealRegister(const QJsonObject &json);//处理注册请求
52 | void dealAvator(const QString &avator);//上传头像
53 | void dealAskforavator(const QString &qqnum);//处理索要头像的请求
54 | void dealFindpassword1(const QString &qqnum);//看看找回的密码是不是有这个账号
55 | void dealFindpassword2(const QJsonObject &json);//查看密保问题回答对了没有 json和全局变量jsonobj一样
56 | void dealFindpassword3(const QJsonObject &json);//修改密码 json和全局变量jsonobj一样
57 | void dealLoginFirst(const QJsonObject &json);//处理用户登录成功后初始化
58 | void dealDeleteFriend(const QJsonObject &json);//处理删除好友的操作
59 | void dealSerachAccount(const QJsonObject &json);//处理用户搜索账户信息的功能
60 | void dealChangeInformation(const QJsonObject &json);//处理用户更新个人信息的功能
61 | void dealChangePassword(const QJsonObject &json);//处理用户更新密码的功能
62 | void dealChangePassword2(const QJsonObject &json);//处理用户更新密码的功能
63 | void dealLogout(const QJsonObject &json);//处理用户注销的功能
64 | void dealAddFriends(const QJsonObject &json);//处理用发送户添加好友申请的功能
65 | void dealAddNewFriends(const QJsonObject &json);//处理用户回应是否添加好友的功能
66 | void dealMessages(const QJsonObject json);//处理用户发送的消息
67 | void sendNextMessage();//从队列发送下一条消息(处理文件)
68 | void dealAskDocument(const QJsonObject &json);//处理用户要下载文件的要求
69 |
70 | public://接收到别的服务器发送的消息 然后转发
71 | void forwordAddFriendRequest(const QJsonObject &json);//向在线用户转发用户好友申请
72 | void forwordRequestPass(const QJsonObject &json);//向在线用户更新他的好友列表(他的好友申请被通过)
73 | void forwordYouAreDeleted(const QJsonObject &json);//向在线用户更新他的好友列表(他被删除了)
74 | void forwordKickedOffline(const QJsonObject &json);//把在线用户挤下线
75 | void forwordMessages(const QJsonObject &json);//向在线用户发送聊天消息
76 |
77 | signals:
78 | void sendMessage(const QJsonObject &json);//给别的客户端发送消息
79 |
80 | private:
81 | static QMutex dbMutex;
82 | static QReadWriteLock lock;
83 | QMutex mutex;
84 | ConnectionPool& pool;
85 | QSqlDatabase db;
86 | QTcpSocket *socket;
87 | QJsonDocument jsonDoc;
88 | QJsonObject jsonObj;
89 | QByteArray jsonData;
90 | QByteArray bufferedData;
91 | Server *srv;//指向服务器的指针
92 | QString randomNumber;//注册随机生成账号
93 | QString account = "0";//登录成功存储账号
94 | QQueue messageQueue; //用于存储待发送的消息
95 | bool isSending = false; //用于标记消息是否正在发送
96 | int flag = 0;
97 | };
98 |
99 |
100 | class DocumentWorker : public QObject//负责查询的类
101 | {
102 | Q_OBJECT
103 | public:
104 | DocumentWorker(const QString &filename, const QString ×tamp, QSqlDatabase db)
105 | : filename(filename), timestamp(timestamp), db(db) {}
106 |
107 | signals:
108 | void resultReady(const QJsonObject &result);
109 |
110 | public slots:
111 | void process();//处理查询文件
112 |
113 | private:
114 | QString filename;
115 | QString timestamp;
116 | QSqlDatabase db;
117 | };
118 |
119 |
120 |
121 | #endif // CLIENTHANDLER_H
122 |
--------------------------------------------------------------------------------
/server/server/connectionpool.cpp:
--------------------------------------------------------------------------------
1 | #include "connectionpool.h"
2 |
3 | ConnectionPool& ConnectionPool::getInstance()//获取单例实例
4 | {
5 | static ConnectionPool instance;//确保是同一个实例
6 | return instance;
7 | }
8 |
9 |
10 | QSqlDatabase ConnectionPool::getConnection() // 获取数据库连接
11 | {
12 | QMutexLocker locker(&mutex);
13 | if (!pool.isEmpty()) {
14 | QSqlDatabase db = pool.dequeue();
15 | if (db.isOpen()) {
16 | qDebug() << "有现成的连接";
17 | return db;
18 | } else {
19 | db.close();
20 | qDebug() << "连接已关闭,丢弃该连接,尝试创建新连接...";
21 | return getConnection();
22 | }
23 | }
24 | //如果没有可用的连接且池未满,则新建连接
25 | if (pool.size() < maxConnections) {
26 | QString connectionName = QString("Connection_%1").arg(connectionCounter++);
27 | QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
28 | db.setDatabaseName(dbName);
29 | if (!db.open()) {
30 | qDebug() << "数据库打开失败:" << db.lastError().text();
31 | return QSqlDatabase();
32 | }
33 | return db; // 返回新连接
34 | } else {
35 | qDebug() << "数据库最大连接数已达到!";
36 | return QSqlDatabase();
37 | }
38 | }
39 |
40 |
41 | void ConnectionPool::releaseConnection(QSqlDatabase db)//释放连接
42 | {
43 | QMutexLocker locker(&mutex);
44 | if (pool.size() < maxConnections) {
45 | pool.enqueue(db);
46 | } else {
47 | db.close();
48 | }
49 | }
50 |
51 |
52 | void ConnectionPool::setMaxConnections(int max)//设置最大连接数
53 | {
54 | QMutexLocker locker(&mutex);
55 | maxConnections = max;
56 | }
57 |
58 |
59 | int ConnectionPool::getMaxConnections() const//获取当前最大连接数
60 | {
61 | return maxConnections;
62 | }
63 |
64 |
65 | ConnectionPool::ConnectionPool() : maxConnections(301)//私有构造函数 默认最大连接数
66 | {
67 | //建立数据库
68 | QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", dbName);
69 | db.setDatabaseName(dbName);
70 | if (!db.open()) {
71 | qDebug() << "打开数据库失败" << db.lastError().text();
72 | }
73 | else{
74 | //检查和创建表的 SQL 语句
75 | QSqlQuery query(db);
76 | //创建用户表
77 | query.exec("CREATE TABLE IF NOT EXISTS Users ("
78 | "qq_number VARCHAR(20) PRIMARY KEY NOT NULL, "
79 | "password VARCHAR(255) NOT NULL, "
80 | "avator LONGTEXT, "
81 | "nickname VARCHAR(50), "
82 | "signature TEXT, "
83 | "gender TEXT CHECK (gender IN ('男', '女', '其他')), "
84 | "question VARCHAR(255), "
85 | "answer VARCHAR(255));");
86 | if (query.lastError().isValid()) {
87 | qDebug() << "创建用户表失败:" << query.lastError().text();
88 | }
89 | //创建聊天消息表
90 | query.exec("CREATE TABLE IF NOT EXISTS Messages ("
91 | "message_id INTEGER PRIMARY KEY AUTOINCREMENT, "
92 | "sender_id VARCHAR(20) NOT NULL, "
93 | "receiver_id VARCHAR(20) NOT NULL, "
94 | "content LONGTEXT, "
95 | "filename VARCHAT(20),"
96 | "status VARCHAT(20),"
97 | "timestamp TIMESTAMP, "
98 | "message_type VARCHAR(20) NOT NULL, "
99 | "FOREIGN KEY (sender_id) REFERENCES Users(qq_number) ON DELETE CASCADE);");
100 | if (query.lastError().isValid()) {
101 | qDebug() << "创建聊天消息表失败:" << query.lastError().text();
102 | }
103 | //创建好友关系表
104 | query.exec("CREATE TABLE IF NOT EXISTS Friends ("
105 | "friendship_id INTEGER PRIMARY KEY AUTOINCREMENT, "
106 | "user_id VARCHAR(20) NOT NULL, "
107 | "friend_id VARCHAR(20) NOT NULL, "
108 | "FOREIGN KEY (user_id) REFERENCES Users(qq_number) ON DELETE CASCADE, "
109 | "FOREIGN KEY (friend_id) REFERENCES Users(qq_number) ON DELETE CASCADE);");
110 | if (query.lastError().isValid()) {
111 | qDebug() << "创建好友关系表失败:" << query.lastError().text();
112 | }
113 | //创建申请表
114 | query.exec("CREATE TABLE IF NOT EXISTS FriendRequests ("
115 | "request_id INTEGER PRIMARY KEY AUTOINCREMENT, "
116 | "sender_id VARCHAR(20) NOT NULL, "
117 | "receiver_id INT NOT NULL, "
118 | "request_type TEXT CHECK (request_type IN ('friend', 'group')) NOT NULL, "
119 | "status TEXT CHECK (status IN ('pending', 'accepted', 'rejected')) NOT NULL DEFAULT 'pending', "
120 | "timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
121 | "FOREIGN KEY (sender_id) REFERENCES Users(qq_number) ON DELETE CASCADE);");
122 | if (query.lastError().isValid()) {
123 | qDebug() << "创建申请表失败:" << query.lastError().text();
124 | }
125 | db.close();
126 | }
127 | }
128 |
129 |
130 | ConnectionPool::~ConnectionPool()//私有析构函数
131 | {
132 | while (!pool.isEmpty()) {
133 | QSqlDatabase db = pool.dequeue();
134 | db.close();//关闭所有连接
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/server/server/connectionpool.h:
--------------------------------------------------------------------------------
1 | #ifndef CONNECTIONPOOL_H
2 | #define CONNECTIONPOOL_H
3 |
4 | #include "qmutex.h"
5 | #include "qsqldatabase.h"
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 |
16 | class ConnectionPool {//连接池
17 | public:
18 | static ConnectionPool& getInstance();//获取单例实例
19 | QSqlDatabase getConnection();//获取数据库连接
20 | void releaseConnection(QSqlDatabase db);//释放连接
21 | void setMaxConnections(int max);//设置最大连接数
22 | int getMaxConnections() const;//获取当前最大连接数
23 |
24 | private:
25 | ConnectionPool();//私有构造函数
26 | ~ConnectionPool();//私有析构函数
27 | QQueue pool;//连接池
28 | QMutex mutex;//互斥锁
29 | int maxConnections;//最大连接数
30 | QString dbName = "suliaoserver.db";//数据库名字
31 | int connectionCounter = 0;//连接个数 起名字
32 | };
33 |
34 | #endif // CONNECTIONPOOL_H
35 |
--------------------------------------------------------------------------------
/server/server/main.cpp:
--------------------------------------------------------------------------------
1 | #include "server.h"
2 |
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | QApplication a(argc, argv);
11 | QTranslator translator;
12 | const QStringList uiLanguages = QLocale::system().uiLanguages();
13 | for (const QString &locale : uiLanguages) {
14 | const QString baseName = "server_" + QLocale(locale).name();
15 | if (translator.load(":/i18n/" + baseName)) {
16 | a.installTranslator(&translator);
17 | break;
18 | }
19 | }
20 | Server w;
21 | w.show();
22 | return a.exec();
23 | }
24 |
--------------------------------------------------------------------------------
/server/server/server.cpp:
--------------------------------------------------------------------------------
1 | #include "server.h"
2 | #include "ui_server.h"
3 | #include "clienthandler.h"
4 |
5 | Server::Server(QWidget *parent)
6 | : QMainWindow(parent)
7 | , ui(new Ui::Server)
8 | {
9 | ui->setupUi(this);
10 | //连接数据库
11 | databasesConnect();
12 | //显示表格
13 | showTable("Users");
14 | ui->table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
15 | //初始化tcp对象
16 | TCP = new QTcpServer(this);
17 | }
18 |
19 |
20 | Server::~Server(){
21 | delete ui;
22 | }
23 |
24 |
25 | bool Server::databasesConnect()//连接数据库
26 | {
27 | ConnectionPool& pool = ConnectionPool::getInstance();//获取连接池实例
28 | Server::db = pool.getConnection();//从连接池获取一个数据库连接
29 | if (!db.isValid()) {//检查连接是否有效
30 | qDebug() << "打开失败: 获取数据库连接失败";
31 | return false;//连接获取失败
32 | } else {
33 | qDebug() << "数据库连接成功";
34 | qry = QSqlQuery(db);//使用有效连接创建查询对象
35 | return true;
36 | }
37 | }
38 |
39 |
40 | void Server::showTable(const QString &tablename)//显示表格
41 | {
42 | QString queryStr;
43 | if (tablename == "Users") {
44 | queryStr = "SELECT qq_number,password,nickname,signature,gender,question,answer FROM Users";
45 | } else if (tablename == "Messages") {
46 | queryStr = "SELECT sender_id,receiver_id,timestamp,message_type,filename,status FROM Messages";
47 | } else if (tablename == "Friends") {
48 | queryStr = "SELECT * FROM Friends";
49 | } else if (tablename == "FriendRequests") {
50 | queryStr = "SELECT * FROM FriendRequests";
51 | }
52 | //创建模型并设置查询
53 | QSqlQueryModel *model = new QSqlQueryModel(this);
54 | model->setQuery(queryStr, Server::db);
55 | if (model->lastError().isValid()) {
56 | qDebug() << "查询失败:" << model->lastError().text();
57 | return;
58 | }
59 | qDebug() << "加载行数:" << model->rowCount();
60 | ui->table->setModel(model);
61 | }
62 |
63 |
64 | bool Server::tcpListen()//建立连接,监听对象
65 | {
66 | connect(TCP, &QTcpServer::newConnection, this, &Server::onNewConnection);
67 | if (!TCP->listen(QHostAddress::Any, 1999)) {
68 | qDebug() << "监听失败:" << TCP->errorString();
69 | return false;
70 | } else {
71 | qDebug() << "监听成功";
72 | return true;
73 | }
74 | }
75 |
76 |
77 | void Server::on_whichtable_currentIndexChanged(int index)//切换表格
78 | {
79 | if(index == 0)
80 | showTable("Users");
81 | if(index == 1)
82 | showTable("Messages");
83 | if(index == 2)
84 | showTable("Friends");
85 | if(index == 3)
86 | showTable("FriendRequests");
87 | }
88 |
89 |
90 | void Server::on_sqlsubmit_clicked()//提交执行SQL语句
91 | {
92 | if (qry.prepare(ui->sql->text()) && qry.exec()) {
93 | showTable(ui->whichtable->currentText());
94 | } else {
95 | qDebug() << "SQL 执行错误:" << qry.lastError().text();
96 | }
97 | }
98 |
99 |
100 | void Server::onNewConnection()//有新连接到来新建clienthandler
101 | {
102 | qDebug()<<"主线程是"<currentThreadId();
103 | QTcpSocket *socket = TCP->nextPendingConnection();
104 | ConnectionPool& pool = ConnectionPool::getInstance();//获取连接池实例
105 | ClientHandler* handler = new ClientHandler(socket, pool, this);
106 | handler->start();
107 | }
108 |
109 |
110 | void Server::on_listen_clicked()//点击开启/关闭服务器 启动/关闭监听
111 | {
112 | if(!listenFlag) {
113 | ui->listen->setText("关闭服务器");
114 | listenFlag = true;
115 | tcpListen();//直接调用当前对象的 tcpListen 方法
116 | } else {
117 | ui->listen->setText("开启服务器");
118 | listenFlag = false;
119 | qDebug()<<"服务器关闭";
120 | TCP->close();//确保关闭 TCP 服务器
121 | }
122 | }
123 |
124 |
125 | void Server::on_pushButton_clicked()//刷新表格
126 | {
127 | qDebug()<<"当前连接的账号有"<whichtable->currentIndex());
129 | }
130 |
131 |
132 |
--------------------------------------------------------------------------------
/server/server/server.h:
--------------------------------------------------------------------------------
1 | #ifndef SERVER_H
2 | #define SERVER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | class ClientHandler;
24 |
25 | QT_BEGIN_NAMESPACE
26 | namespace Ui {
27 | class Server;
28 | }
29 | QT_END_NAMESPACE
30 |
31 |
32 | class Server : public QMainWindow
33 | {
34 | Q_OBJECT
35 |
36 | public:
37 | explicit Server(QWidget *parent = nullptr);
38 | ~Server();
39 | bool databasesConnect();//连接数据库
40 | void showTable(const QString &tablename);//显示表格
41 | bool tcpListen();//建立连接,监听对象
42 |
43 | private slots:
44 | void on_whichtable_currentIndexChanged(int index);//切换表格
45 | void on_sqlsubmit_clicked();//使用SQL语句
46 | void onNewConnection();//有新连接到来新建clienthandler
47 | void on_listen_clicked();//点击开启/关闭服务器 启动/关闭监听
48 | void on_pushButton_clicked();//刷新表格
49 |
50 | private:
51 | Ui::Server *ui;
52 | QThreadPool *threadPool;//线程池
53 | QMutex mapMutex; // 互斥量,确保线程安全
54 | QSqlDatabase db;
55 | QSqlQuery qry;
56 | QTcpServer *TCP;
57 | bool listenFlag = false;
58 |
59 | public:
60 | QHash clientsMap;//存储账号与ClientHandler的映射 共享资源
61 | };
62 |
63 | #endif // SERVER_H
64 |
--------------------------------------------------------------------------------
/server/server/server.pro:
--------------------------------------------------------------------------------
1 | QT += core gui \
2 | quick
3 | QT += core gui sql
4 | QT += sql
5 | QT += core network
6 |
7 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
8 |
9 | CONFIG += c++17
10 |
11 | # You can make your code fail to compile if it uses deprecated APIs.
12 | # In order to do so, uncomment the following line.
13 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
14 |
15 | SOURCES += \
16 | clienthandler.cpp \
17 | connectionpool.cpp \
18 | main.cpp \
19 | server.cpp
20 |
21 | HEADERS += \
22 | clienthandler.h \
23 | connectionpool.h \
24 | server.h
25 |
26 | FORMS += \
27 | server.ui
28 |
29 | TRANSLATIONS += \
30 | server_zh_CN.ts
31 | CONFIG += lrelease
32 | CONFIG += embed_translations
33 |
34 | # Default rules for deployment.
35 | qnx: target.path = /tmp/$${TARGET}/bin
36 | else: unix:!android: target.path = /opt/$${TARGET}/bin
37 | !isEmpty(target.path): INSTALLS += target
38 |
--------------------------------------------------------------------------------
/server/server/server.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Server
4 |
5 |
6 |
7 | 0
8 | 0
9 | 1100
10 | 600
11 |
12 |
13 |
14 |
15 | 1100
16 | 600
17 |
18 |
19 |
20 |
21 | 1100
22 | 600
23 |
24 |
25 |
26 | server
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | 20
36 | 10
37 | 1061
38 | 561
39 |
40 |
41 |
42 | -
43 |
44 |
-
45 |
46 |
47 |
48 | 50
49 | 50
50 |
51 |
52 |
53 |
54 | 150
55 | 32
56 |
57 |
58 |
59 | font: 10pt "Microsoft YaHei UI";
60 |
61 |
62 |
63 |
-
64 |
65 | Users
66 |
67 |
68 | -
69 |
70 | Messages
71 |
72 |
73 | -
74 |
75 | Friends
76 |
77 |
78 | -
79 |
80 | FriendRequests
81 |
82 |
83 |
84 |
85 | -
86 |
87 |
88 |
89 | 0
90 | 9
91 |
92 |
93 |
94 |
95 | 80
96 | 27
97 |
98 |
99 |
100 | QPushButton{
101 | font: 10pt "Microsoft YaHei UI";
102 | border: 1px solid rgba(0, 0, 0, 0.3);
103 | }
104 | QPushButton:pressed {
105 | font: 10pt "Microsoft YaHei UI";
106 | border: 1px solid rgba(0, 0, 0, 0.3);
107 | background-color: rgb(255, 251, 255);
108 | }
109 |
110 |
111 | 开启服务器
112 |
113 |
114 | false
115 |
116 |
117 | false
118 |
119 |
120 | false
121 |
122 |
123 |
124 | -
125 |
126 |
127 |
128 | 0
129 | 10
130 |
131 |
132 |
133 |
134 | 80
135 | 27
136 |
137 |
138 |
139 | QPushButton{
140 | font: 10pt "Microsoft YaHei UI";
141 | border: 1px solid rgba(0, 0, 0, 0.3);
142 | }
143 | QPushButton:pressed {
144 | font: 10pt "Microsoft YaHei UI";
145 | border: 1px solid rgba(0, 0, 0, 0.3);
146 | background-color: rgb(255, 251, 255);
147 | }
148 |
149 |
150 | 刷新表格
151 |
152 |
153 |
154 |
155 |
156 | -
157 |
158 |
159 |
160 | 50
161 | 50
162 |
163 |
164 |
165 | font: 10pt "Microsoft YaHei UI";
166 | border: 1px solid rgba(0, 0, 0, 0.3);
167 |
168 |
169 |
170 | false
171 |
172 |
173 | false
174 |
175 |
176 | false
177 |
178 |
179 | false
180 |
181 |
182 |
183 | -
184 |
185 |
-
186 |
187 |
188 |
189 | 50
190 | 50
191 |
192 |
193 |
194 | font: 12pt "Microsoft YaHei UI";
195 | border: 1px solid rgba(0, 0, 0, 0.3);
196 |
197 |
198 |
199 | 请输入SQL语句
200 |
201 |
202 |
203 | -
204 |
205 |
206 |
207 | 5
208 | 50
209 |
210 |
211 |
212 | QPushButton{
213 | font: 12pt "Microsoft YaHei UI";
214 | border: 1px solid rgba(0, 0, 0, 0.3);
215 | }
216 | QPushButton:pressed {
217 | font: 12pt "Microsoft YaHei UI";
218 | border: 1px solid rgba(0, 0, 0, 0.3);
219 | background-color: rgb(255, 251, 255);
220 | }
221 |
222 |
223 | 提交
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
242 |
243 |
244 |
245 |
246 |
247 |
--------------------------------------------------------------------------------
/server/server/server_zh_CN.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/user/user/addfriends.cpp:
--------------------------------------------------------------------------------
1 | #include "addfriends.h"
2 | #include "ui_addfriends.h"
3 | #include "autocleartextedit.h"
4 | #include "dialog.h"
5 | #include "choicedialog.h"
6 |
7 | AddFriends::AddFriends(QWidget *parent)
8 | : QDialog(parent)
9 | , ui(new Ui::AddFriends)
10 | {
11 | ui->setupUi(this);
12 | //初始化窗口
13 | QIcon icon(":/pictures/suliao.png");
14 | setWindowIcon(icon);
15 | setWindowFlags( Qt::FramelessWindowHint | Qt::Dialog);
16 | setAttribute(Qt::WA_TranslucentBackground);//允许背景透明
17 | //清除输入框焦点
18 | ui->line_serach->clearFocus();
19 | // 将窗口居中显示
20 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
21 | if (topLevelParent) {
22 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
23 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
24 | move(x, y);
25 | }
26 | }
27 |
28 |
29 | AddFriends::~AddFriends()
30 | {
31 | delete ui;
32 | //this->disconnect();放在主窗口的槽函数中了
33 | qDebug()<<"添加好友窗口析构函数执行";
34 | }
35 |
36 |
37 | void AddFriends::paintEvent(QPaintEvent *event)//窗口背景
38 | {
39 | //调用基类方法以处理父类的绘图
40 | QDialog::paintEvent(event);
41 | QPainter painter(this);
42 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
43 | //加载背景图片
44 | QPixmap background(":/pictures/094 Cloudy Apple - trans.png");
45 | //确保图片已加载
46 | if (background.isNull()) {
47 | qWarning("背景图像加载失败");
48 | return;
49 | }
50 | QSize newSize = QSize(this->width(), this->height());
51 | //将背景图缩放为新的大小
52 | QPixmap scaledBackground = background.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
53 | //计算绘制的位置,保持居中
54 | int x = (this->width() - scaledBackground.width()) / 2;
55 | int y = (this->height() - scaledBackground.height()) / 2;
56 | //设置剪裁区域以适应圆角窗口
57 | int radius = 10;
58 | QPainterPath path;
59 | path.addRoundedRect(rect(), radius, radius);
60 | painter.setClipPath(path);
61 | //绘制背景图片
62 | painter.drawPixmap(x, y, scaledBackground);
63 | //绘制边框
64 | painter.setPen(QPen(Qt::gray, 3.5));
65 | painter.drawRoundedRect(rect(), radius, radius);
66 | }
67 |
68 |
69 | void AddFriends::mousePressEvent(QMouseEvent *event)//捕获鼠标按下事件
70 | {
71 | //清除焦点
72 | QList widgets = this->findChildren();
73 | for (QWidget* widget : widgets) {
74 | widget->clearFocus();
75 | }
76 | QPoint pos = event->pos();
77 | int margin = 30;
78 | if (pos.x() <= 30 || pos.x() >= width() - 30 ||
79 | pos.y() <= 30 || pos.y() >= height() - 30){//如果点击在边缘
80 | qDebug() << "点击在边缘";
81 | moveFlag = 1;
82 | dragPosition = event->globalPosition().toPoint() - this->frameGeometry().topLeft();//记录鼠标相对于窗口的初始偏移
83 | event->accept();
84 | }
85 | }
86 |
87 |
88 | void AddFriends::mouseMoveEvent(QMouseEvent *event)//实现拖拽移动效果与调整大小效果
89 | {
90 | qDebug()<<"鼠标位移了";
91 | QPoint globalPos = event->globalPosition().toPoint();//获取当前的鼠标位置
92 | QPoint delta = globalPos - (this->frameGeometry().topLeft() + dragPosition);//计算当前鼠标位置与窗口之间的相对偏移
93 | if (event->buttons() & Qt::LeftButton) {
94 | if (moveFlag == 1) {
95 | this->move(globalPos - dragPosition);
96 | event->accept();
97 | }
98 | //更新拖动位置
99 | dragPosition = globalPos - this->frameGeometry().topLeft();
100 | }
101 | }
102 |
103 |
104 | void AddFriends::mouseReleaseEvent(QMouseEvent *event)//重置移动状态
105 | {
106 | moveFlag = 0;
107 | }
108 |
109 |
110 | void AddFriends:: closeEvent(QCloseEvent *event)//关闭窗口事件
111 | {
112 | emit customClose();//this->disconnect();放在主窗口的槽函数中了
113 | this->deleteLater();
114 | event->accept();
115 | }
116 |
117 |
118 | void AddFriends::on_but_deletewindow_clicked()//关闭窗口按钮
119 | {
120 | this->close();
121 | }
122 |
123 |
124 | void AddFriends::on_line_serach_returnPressed()//搜索好友
125 | {
126 | if(ui->line_serach->text() == "输入对方账号搜索" || ui->line_serach->text().length() != 10){
127 | QString text = "请输入正确的账号。";
128 | Dialog* dialog = new Dialog(this);
129 | dialog->transText(text);
130 | dialog->exec();
131 | return;
132 | }
133 | emit serachFriends(ui->line_serach->text());
134 | ui->line_serach->clearFocus();
135 | }
136 |
137 |
138 | void AddFriends::on_but_fangdajing_clicked()//点击放大镜也是搜索
139 | {
140 | on_line_serach_returnPressed();
141 | }
142 |
143 |
144 | void AddFriends::serachResult(const QJsonObject &json)//查找账号的结果
145 | {
146 | if(json["answer"] == "fail"){
147 | QString text = "没有找到用户,请检查您输入的账号。";
148 | Dialog* dialog = new Dialog(this);
149 | dialog->transText(text);
150 | dialog->exec();
151 | }
152 | else if(json["answer"] == "succeed"){
153 | //删除旧控件
154 | QLayoutItem *item;
155 | while ((item = ui->layout_frame->takeAt(0)) != nullptr) {
156 | delete item->widget();//删除控件
157 | delete item;//删除布局项
158 | }
159 | //添加间隔器
160 | QSpacerItem *spacertop = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
161 | ui->layout_frame->addItem(spacertop);
162 | //添加信息标签
163 | auto addTextEditWithStyle = [&](const QString &prefix, const QString &text) {
164 | AutoClearTextEdit *textEdit = new AutoClearTextEdit(prefix + text);
165 | textEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
166 | textEdit->setFixedSize(300, 42);
167 | textEdit->setStyleSheet(
168 | "font-size: 15px; "
169 | "color: #333333; "
170 | "font-weight: bold; "
171 | "padding: 5px; "
172 | "background: rgba(255, 255, 255 , 10); "
173 | "border: 1.5px solid black; "
174 | "border-radius: 5px;");
175 | textEdit->setAlignment(Qt::AlignCenter);
176 | textEdit->setReadOnly(true);//设置为只读
177 | textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用垂直滚动条
178 | textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用水平滚动条
179 | return textEdit;
180 | };
181 | //获取用户信息
182 | accountNum = json["account_num"].toString();
183 | QString nickname = json["nickname"].toString();
184 | QString gender = json["gender"].toString();
185 | QString birthday = json["birthday"].toString();
186 | QString signature = json["signature"].toString();
187 | QString avator = json["avator"].toString();//base64
188 | QByteArray byteArray = QByteArray::fromBase64(avator.toUtf8());
189 | QImage image;
190 | image.loadFromData(byteArray);
191 | QPixmap pixmap = QPixmap::fromImage(image);
192 | //显示头像
193 | QLabel *avatorLabel = new QLabel;
194 | avatorLabel->setPixmap(pixmap);
195 | avatorLabel->setScaledContents(true);
196 | avatorLabel->setFixedSize(120, 120);
197 | avatorLabel->setAlignment(Qt::AlignCenter);
198 | avatorLabel->setStyleSheet("border: 3px solid black; border-radius: 8px;");
199 | ui->layout_frame->addWidget(avatorLabel, 0, Qt::AlignCenter);
200 | //添加间隔器
201 | QSpacerItem *spacer0 = new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed);
202 | ui->layout_frame->addItem(spacer0);
203 | //添加信息
204 | if (!nickname.isEmpty()) ui->layout_frame->addWidget(addTextEditWithStyle("昵称: ", nickname), 0, Qt::AlignCenter);
205 | if (!accountNum.isEmpty()) ui->layout_frame->addWidget(addTextEditWithStyle("账号: ", accountNum), 0, Qt::AlignCenter);
206 | if (!gender.isEmpty()) ui->layout_frame->addWidget(addTextEditWithStyle("性别: ", gender), 0, Qt::AlignCenter);
207 | if (!birthday.isEmpty()) ui->layout_frame->addWidget(addTextEditWithStyle("生日: ", birthday), 0, Qt::AlignCenter);
208 | if (!signature.isEmpty()) ui->layout_frame->addWidget(addTextEditWithStyle("签名: ", signature), 0, Qt::AlignCenter);
209 | //添加间隔器
210 | QSpacerItem *spacer1 = new QSpacerItem(0, 3, QSizePolicy::Fixed, QSizePolicy::Fixed);
211 | ui->layout_frame->addItem(spacer1);
212 | //添加添加好友按钮
213 | QPushButton *addButton = new QPushButton("添加好友");
214 | addButton->setCursor(Qt::PointingHandCursor);
215 | addButton->setFixedSize(180, 55);
216 | addButton->setStyleSheet(
217 | "QPushButton {"
218 | " font: 12pt 'Microsoft YaHei UI';"
219 | " background-color: rgb(5, 186, 251);"
220 | " color: white;"
221 | " font-weight: bold; "
222 | " border-radius: 15px;"
223 | "}"
224 | "QPushButton:hover {"
225 | " background-color: rgba(5, 186, 251, 0.7);"
226 | " font-weight: bold; "
227 | " color: white;"
228 | " border-radius: 15px;"
229 | "}"
230 | "QPushButton:pressed {"
231 | " background-color: rgba(0, 123, 255, 0.8);"
232 | " font-weight: bold; "
233 | " color: rgba(255, 255, 255, 0.9);"
234 | " border-radius: 15px;"
235 | "}"
236 | );
237 | ui->layout_frame->addWidget(addButton, 0, Qt::AlignCenter);
238 | //增加间距
239 | ui->layout_frame->setSpacing(3);
240 | ui->layout_frame->setContentsMargins(5, 5, 5, 5);
241 | //添加间隔器
242 | QSpacerItem *spacer2 = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
243 | ui->layout_frame->addItem(spacer2);
244 | addButton->setFocusPolicy(Qt::ClickFocus);
245 | //为按钮添加点击事件
246 | connect(addButton, &QPushButton::clicked, this, [&]() {
247 | qDebug() << "添加好友按钮被点击";
248 | ChoiceDialog dialog(this);
249 | dialog.transText("你确定要添加好友吗?");
250 | dialog.transButText("确定","取消");
251 | int result = dialog.exec();
252 | if (result == QDialog::Accepted) {
253 | emit addFriend(accountNum);
254 | }
255 | });
256 | }
257 | }
258 |
259 |
260 | void LineSerach_2::focusInEvent(QFocusEvent *event)//搜索框获得焦点
261 | {
262 | setStyleSheet("font: 450 11pt 'Microsoft YaHei UI Light'; "
263 | "border: 1px solid rgba(0, 0, 0, 0.3); "
264 | "border-radius: 5px; "
265 | "border: none;"
266 | "padding:5px;"
267 | "color: black;");
268 | if(text() == "输入对方账号搜索"){
269 | setText("");
270 | }
271 | QLineEdit::focusInEvent(event);
272 | }
273 |
274 |
275 | void LineSerach_2::focusOutEvent(QFocusEvent *event)//搜索失去焦点
276 | {
277 | setStyleSheet("font: 450 11pt 'Microsoft YaHei UI Light'; "
278 | "border: 1px solid rgba(0, 0, 0, 0.3); "
279 | "border-radius: 5px; "
280 | "border: none;"
281 | "padding:5px;"
282 | "color: grey;");
283 | if (text().isEmpty()) {
284 | setText("输入对方账号搜索");
285 | setStyleSheet("font: 400 11pt 'Microsoft YaHei UI Light'; "
286 | "border: 1px solid rgba(0, 0, 0, 0.3); "
287 | "border-radius: 5px; "
288 | "border: none;"
289 | "padding:5px;"
290 | "color: grey;");
291 | }
292 | QLineEdit::focusOutEvent(event);
293 | }
294 |
295 |
296 |
297 |
298 |
--------------------------------------------------------------------------------
/user/user/addfriends.h:
--------------------------------------------------------------------------------
1 | #ifndef ADDFRIENDS_H
2 | #define ADDFRIENDS_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | namespace Ui {
14 | class AddFriends;
15 | }
16 |
17 |
18 | class AddFriends : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | explicit AddFriends(QWidget *parent = nullptr);
24 | ~AddFriends();
25 | void paintEvent(QPaintEvent *event);//窗口背景
26 | void mousePressEvent(QMouseEvent *event);//捕获鼠标按下事件
27 | void mouseMoveEvent(QMouseEvent *event);//实现拖拽移动效果与调整大小效果
28 | void mouseReleaseEvent(QMouseEvent *event);//重置移动状态
29 |
30 | protected:
31 | void closeEvent(QCloseEvent *event);//关闭窗口事件
32 |
33 | private slots:
34 | void on_but_deletewindow_clicked();//关闭窗口按钮
35 | void on_line_serach_returnPressed();//搜索好友
36 | void on_but_fangdajing_clicked();//点击放大镜也是搜索
37 |
38 | public slots:
39 | void serachResult(const QJsonObject &json);//查找账号的结果
40 |
41 | signals:
42 | void serachFriends(const QString &account);//向主窗体发送搜索账号信息
43 | void customClose();//向主窗体发送信号 表示已经关闭了
44 | void addFriend(const QString &friendAccount);//向主窗体发送信号 表示添加好友
45 |
46 | private:
47 | Ui::AddFriends *ui;
48 | QString accountNum;//搜索到的账号
49 | QPoint dragPosition;
50 | int moveFlag = 0;
51 | };
52 |
53 |
54 | class LineSerach_2 :public QLineEdit//搜索框类
55 | {
56 | Q_OBJECT
57 |
58 | public:
59 | LineSerach_2(QWidget *parent = nullptr) : QLineEdit(parent) {}
60 |
61 | public slots:
62 | void focusInEvent(QFocusEvent *event);//搜索框获得焦点
63 | void focusOutEvent(QFocusEvent *event);//搜索失去焦点
64 | };
65 |
66 | #endif // ADDFRIENDS_H
67 |
--------------------------------------------------------------------------------
/user/user/addfriends.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | AddFriends
4 |
5 |
6 |
7 | 0
8 | 0
9 | 530
10 | 530
11 |
12 |
13 |
14 |
15 | 0
16 | 0
17 |
18 |
19 |
20 | Qt::ContextMenuPolicy::DefaultContextMenu
21 |
22 |
23 | 添加好友
24 |
25 |
26 |
27 |
28 |
29 | border:none
30 |
31 |
32 | false
33 |
34 |
35 | -
36 |
37 |
38 |
39 | 0
40 | 15
41 |
42 |
43 |
44 |
45 | 20
46 | 20
47 |
48 |
49 |
50 |
51 | 20
52 | 20
53 |
54 |
55 |
56 | QPushButton {
57 | border: none;
58 | background: transparent;
59 | color: rgb(78, 78, 78);
60 | font: 16pt 'Microsoft New Tai Lue';
61 | }
62 |
63 | QPushButton:hover {
64 | border: none;
65 | background: transparent;
66 | color: white;
67 | font: 16pt 'Microsoft New Tai Lue';
68 | background: red;
69 | border-radius: 3px;
70 | }
71 |
72 |
73 | x
74 |
75 |
76 | false
77 |
78 |
79 |
80 | -
81 |
82 |
-
83 |
84 |
-
85 |
86 |
87 |
88 | 0
89 | 0
90 |
91 |
92 |
93 |
94 | 480
95 | 30
96 |
97 |
98 |
99 |
100 | 460
101 | 30
102 |
103 |
104 |
105 | false
106 |
107 |
108 | Qt::FocusPolicy::ClickFocus
109 |
110 |
111 | border-radius: 5px;
112 | border: none;
113 | padding:5px;
114 | font: 400 11pt "Microsoft YaHei UI Light";
115 | color:grey;
116 |
117 |
118 | 输入对方账号搜索
119 |
120 |
121 | 12
122 |
123 |
124 |
125 | -
126 |
127 |
128 |
129 | 0
130 | 0
131 |
132 |
133 |
134 |
135 | 30
136 | 30
137 |
138 |
139 |
140 | PointingHandCursor
141 |
142 |
143 | background:transparent;
144 | border: none;
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | false
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | -
163 |
164 |
165 |
166 | 0
167 | 210
168 |
169 |
170 |
171 |
172 | 0
173 | 210
174 |
175 |
176 |
177 | border-radius: 10px;
178 | border: 0.5px solid rgb(180, 180, 180);
179 |
180 |
181 |
182 | QFrame::Shape::StyledPanel
183 |
184 |
185 | QFrame::Shadow::Raised
186 |
187 |
188 |
-
189 |
190 |
191 |
192 |
193 |
194 | -
195 |
196 |
197 |
198 | 0
199 | 0
200 |
201 |
202 |
203 | Qt::ContextMenuPolicy::NoContextMenu
204 |
205 |
206 | font: 700 11pt "Microsoft YaHei UI";
207 |
208 |
209 | 添加好友
210 |
211 |
212 | Qt::AlignmentFlag::AlignCenter
213 |
214 |
215 |
216 | -
217 |
218 |
219 | Qt::Orientation::Horizontal
220 |
221 |
222 | QSizePolicy::Policy::Fixed
223 |
224 |
225 |
226 | 1
227 | 20
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 | LineSerach_2
237 | QLineEdit
238 |
239 |
240 |
241 |
242 |
243 |
244 |
--------------------------------------------------------------------------------
/user/user/autocleartextedit.cpp:
--------------------------------------------------------------------------------
1 | #include "autocleartextedit.h"
2 |
3 | AutoClearTextEdit::AutoClearTextEdit(QWidget *parent)
4 | : QTextEdit(parent)
5 | {
6 | }
7 |
8 |
9 | AutoClearTextEdit::AutoClearTextEdit(const QString &text, QWidget *parent)
10 | : QTextEdit(parent)
11 | {
12 | setPlainText(text);//设置初始文本
13 | }
14 |
15 |
16 | void AutoClearTextEdit::focusOutEvent(QFocusEvent *event)
17 | {
18 | QTextCursor cursor = this->textCursor();
19 | cursor.clearSelection();//取消选择
20 | this->setTextCursor(cursor);//更新光标状态
21 | QTextEdit::focusOutEvent(event);//调用基类的事件处理
22 | }
23 |
--------------------------------------------------------------------------------
/user/user/autocleartextedit.h:
--------------------------------------------------------------------------------
1 | #ifndef AUTOCLEARTEXTEDIT_H
2 | #define AUTOCLEARTEXTEDIT_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | class AutoClearTextEdit : public QTextEdit//可以自动取消选择文字的textedit
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit AutoClearTextEdit(QWidget *parent = nullptr);
16 | explicit AutoClearTextEdit(const QString &text, QWidget *parent = nullptr);//新增构造函数
17 |
18 | protected:
19 | void focusOutEvent(QFocusEvent *event) override;
20 | };
21 |
22 | #endif // AUTOCLEARTEXTEDIT_H
23 |
--------------------------------------------------------------------------------
/user/user/changeinformation.cpp:
--------------------------------------------------------------------------------
1 | #include "changeinformation.h"
2 | #include "qpainterpath.h"
3 | #include "ui_changeinformation.h"
4 | #include "dialog.h"
5 | #include "cutavator.h"
6 |
7 | ChangeInformation::ChangeInformation(MyAccountInfo info, QWidget *parent)
8 | : QDialog(parent)
9 | , ui(new Ui::ChangeInformation)
10 | , actInfo(info)
11 | {
12 | ui->setupUi(this);
13 | //初始化窗口
14 | QIcon icon(":/pictures/suliao.png");
15 | setWindowIcon(icon);
16 | setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
17 | setAttribute(Qt::WA_TranslucentBackground);
18 | //设置当前页面各信息
19 | setMessage(actInfo);
20 | // 将窗口居中显示
21 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
22 | if (topLevelParent) {
23 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
24 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
25 | move(x, y);
26 | }
27 | }
28 |
29 |
30 | ChangeInformation::~ChangeInformation()
31 | {
32 | delete ui;
33 | qDebug()<<"修改个人信息窗口析构函数被调用";
34 | disconnect();
35 | }
36 |
37 |
38 | void ChangeInformation::paintEvent(QPaintEvent *event)//窗口背景
39 | {
40 | //调用基类方法以处理父类的绘图
41 | QDialog::paintEvent(event);
42 | QPainter painter(this);
43 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
44 | //加载背景图片
45 | QPixmap background(":/pictures/094 Cloudy Apple - trans.png");
46 | //确保图片已加载
47 | if (background.isNull()) {
48 | qWarning("背景图像加载失败");
49 | return;
50 | }
51 | QSize newSize = QSize(this->width(), this->height());
52 | //将背景图缩放为新的大小
53 | QPixmap scaledBackground = background.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
54 | //计算绘制的位置,保持居中
55 | int x = (this->width() - scaledBackground.width()) / 2;
56 | int y = (this->height() - scaledBackground.height()) / 2;
57 | //设置剪裁区域以适应圆角窗口
58 | int radius = 10;
59 | QPainterPath path;
60 | path.addRoundedRect(rect(), radius, radius);
61 | painter.setClipPath(path);
62 | //绘制背景图片
63 | painter.drawPixmap(x, y, scaledBackground);
64 | //绘制边框
65 | painter.setPen(QPen(Qt::gray, 3.5));
66 | painter.drawRoundedRect(rect(), radius, radius);
67 | }
68 |
69 |
70 | void ChangeInformation::mousePressEvent(QMouseEvent *event)//捕获鼠标按下事件
71 | {
72 | //清除焦点
73 | QList widgets = this->findChildren();
74 | for (QWidget* widget : widgets) {
75 | widget->clearFocus();
76 | }
77 | QPoint pos = event->pos();
78 | int margin = 30;
79 | if (pos.x() <= 30 || pos.x() >= width() - 30 ||
80 | pos.y() <= 30 || pos.y() >= height() - 30){//如果点击在边缘
81 | qDebug() << "点击在边缘";
82 | moveFlag = 1;
83 | dragPosition = event->globalPosition().toPoint() - this->frameGeometry().topLeft();//记录鼠标相对于窗口的初始偏移
84 | event->accept();
85 | }
86 | }
87 |
88 |
89 | void ChangeInformation::mouseMoveEvent(QMouseEvent *event)//实现拖拽移动效果与调整大小效果
90 | {
91 | qDebug()<<"鼠标位移了";
92 | QPoint globalPos = event->globalPosition().toPoint();//获取当前的鼠标位置
93 | QPoint delta = globalPos - (this->frameGeometry().topLeft() + dragPosition);//计算当前鼠标位置与窗口之间的相对偏移
94 | if (event->buttons() & Qt::LeftButton) {
95 | if (moveFlag == 1) {
96 | this->move(globalPos - dragPosition);
97 | event->accept();
98 | }
99 | //更新拖动位置
100 | dragPosition = globalPos - this->frameGeometry().topLeft();
101 | }
102 | }
103 |
104 |
105 | void ChangeInformation::mouseReleaseEvent(QMouseEvent *event)//重置移动状态
106 | {
107 | moveFlag = 0;
108 | }
109 |
110 |
111 | QString ChangeInformation::pixmapToBase64(const QPixmap &pixmap)//图片转换成base64格式
112 | {
113 | QImage image = pixmap.toImage();
114 | QBuffer buffer;
115 | buffer.open(QIODevice::WriteOnly);
116 | image.save(&buffer, "PNG");
117 | QByteArray byteArray = buffer.data();
118 | return QString(byteArray.toBase64());
119 | }
120 |
121 |
122 | QPixmap ChangeInformation::base64ToPixmap(const QString &base64Str)//将base64转换为图片
123 | {
124 | QByteArray byteArray = QByteArray::fromBase64(base64Str.toUtf8());
125 | QImage image;
126 | //尝试加载PNG格式
127 | if (!image.loadFromData(byteArray, "PNG")) {
128 | //如果PNG加载失败,尝试JPG格式
129 | image.loadFromData(byteArray, "JPG");
130 | }
131 | return QPixmap::fromImage(image);
132 | }
133 |
134 |
135 | void ChangeInformation::setMessage(const MyAccountInfo &info)//设置当前页面各信息
136 | {
137 | ui->textEdit_account->setText(info.account);
138 | ui->line_nickname->setText(info.name);
139 | ui->line_sig->setText(info.signature);
140 | QPixmap avator = base64ToPixmap(info.avator_base64);
141 | ui->lab_avator->setScaledContents(true);
142 | ui->lab_avator->setPixmap(avator);
143 | if(info.gender == "其他"){
144 | ui->cbbox_sex->setCurrentIndex(0);
145 | }
146 | else if(info.gender == "男"){
147 | ui->cbbox_sex->setCurrentIndex(1);
148 | }
149 | else{
150 | ui->cbbox_sex->setCurrentIndex(2);
151 | }
152 | }
153 |
154 |
155 | void ChangeInformation::judgeMessage()//判断能否点击确认
156 | {
157 | int flag = 0;//初始不可点击
158 | if(avaFlag == 1){//头像修改了 则标记可点击
159 | flag = 1;
160 | }
161 | if(ui->line_nickname->text() != actInfo.name || ui->line_sig->text() != actInfo.signature || ui->cbbox_sex->currentText() != actInfo.gender){
162 | flag = 1;//有信息修改过 则标记可点击
163 | }
164 | if(ui->line_nickname->text() == ""){//任何情况昵称为空 则不可修改
165 | flag = 0;
166 | }
167 | if(flag == 0){
168 | ui->but_yes->setStyleSheet(
169 | "QPushButton {"
170 | "font: 12pt 'Microsoft YaHei UI';"
171 | "background-color: rgb(167, 214, 255); "
172 | "color: white;"
173 | "border-radius: 10px;"
174 | "}"
175 | );
176 | ui->but_yes->setEnabled(false);
177 | }
178 | else{
179 | ui->but_yes->setStyleSheet(
180 | "QPushButton {"
181 | "font: 12pt 'Microsoft YaHei UI';"
182 | "background-color: rgb(5, 186, 251);"
183 | "color: white;"
184 | "border-radius: 10px;"
185 | "border: 0.5px solid rgb(220, 220, 220);"
186 | "}"
187 | "QPushButton:hover {"
188 | "background-color: rgba(5, 186, 251, 0.7);"
189 | "color: white;"
190 | "border-radius: 10px;"
191 | "}"
192 | "QPushButton:pressed {"
193 | "background-color: rgba(0, 123, 255, 0.8);"
194 | "color: rgba(255, 255, 255, 0.9);"
195 | "border-radius: 10px;"
196 | "}"
197 | );
198 | ui->but_yes->setEnabled(true);
199 | }
200 | }
201 |
202 |
203 | void ChangeInformation::on_but_cancelwindow_clicked()//关闭窗口
204 | {
205 | emit customClose();
206 | this->close();
207 | this->deleteLater();
208 | }
209 |
210 |
211 | void ChangeInformation::on_but_no_clicked()//点击取消 也关闭窗口
212 | {
213 | on_but_cancelwindow_clicked();
214 | }
215 |
216 |
217 | void ChangeInformation::on_cbbox_sex_currentIndexChanged(int index)//改变性别 判断能否点击确认
218 | {
219 | judgeMessage();
220 | }
221 |
222 |
223 | void ChangeInformation::on_line_nickname_textChanged(const QString &arg1)//昵称文本框文字改变 判断是否能点击确认
224 | {
225 | judgeMessage();
226 | }
227 |
228 |
229 | void ChangeInformation::on_line_sig_textChanged(const QString &arg1)//个性签名文本框改变 判断是否能点击确认
230 | {
231 | judgeMessage();
232 | }
233 |
234 |
235 | void ChangeInformation::on_but_yes_clicked()//发送修改申请
236 | {
237 | MyAccountInfo tmpInfo;
238 | tmpInfo.account = ui->textEdit_account->toPlainText();
239 | tmpInfo.signature = ui->line_sig->text();
240 | tmpInfo.gender = ui->cbbox_sex->currentText();
241 | tmpInfo.name = ui->line_nickname->text();
242 | tmpInfo.avator_base64 = pixmapToBase64(ui->lab_avator->pixmap());
243 | sendMessage(tmpInfo);
244 | ui->but_yes->setEnabled(false);
245 | }
246 |
247 |
248 | void ChangeInformation::getAva(const QPixmap &pixmap)//子窗口剪切好头像 收到头像 更新并判断能否点击确认
249 | {
250 | ui->lab_avator->setPixmap(pixmap);
251 | avaFlag = 1;
252 | judgeMessage();
253 | }
254 |
255 |
256 | void ChangeInformation::dealResult(const QJsonObject &json)//处理修改资料的结果
257 | {
258 | if(json["answer"] == "succeed"){//成功则修改个人资料
259 | actInfo.account = json["account"].toString();
260 | actInfo.name = json["nickname"].toString();
261 | actInfo.gender = json["gender"].toString();
262 | actInfo.signature = json["signature"].toString();
263 | actInfo.avator_base64 = json["avator"].toString();
264 | setMessage(actInfo);//重新设置个人资料
265 | avaFlag = 0;
266 | judgeMessage();//判断是否可以点击
267 | QString text = "修改成功!";
268 | Dialog* dialog = new Dialog(this);
269 | dialog->transText(text);
270 | dialog->exec();
271 | emit customClose();
272 | close();
273 | }
274 | else if(json["answer"] == "fail"){
275 | qDebug()<<"修改资料失败";
276 | QString text = "修改失败!";
277 | Dialog* dialog = new Dialog(this);
278 | dialog->transText(text);
279 | dialog->exec();
280 | judgeMessage();//判断是否可以点击
281 | }
282 | }
283 |
284 |
285 | void LineMessage::focusInEvent(QFocusEvent *event)//获得焦点处理事件
286 | {
287 | if(flag == 0){
288 | setText("");
289 | flag = 1;
290 | }
291 | QLineEdit::focusInEvent(event);
292 | }
293 |
294 |
295 | void LineMessage::focusOutEvent(QFocusEvent *event)//失去焦点处理事件
296 | {
297 | QLineEdit::focusOutEvent(event);
298 | }
299 |
300 |
301 | void LabelChooseAva::mousePressEvent(QMouseEvent *event)//点击头像更换头像
302 | {
303 | qDebug() << "点击头像了";
304 | QString filename = QFileDialog::getOpenFileName(this, "选择图片", "", "Images (*.png *.jpg *.jpeg *.bmp *.gif)");
305 | if (!filename.isEmpty()) {
306 | qDebug() << "头像路径有效";
307 | QPixmap pixmap(filename);
308 | if (pixmap.isNull()) {
309 | qDebug() << "加载图片失败";
310 | return;
311 | }
312 | //打开头像编辑器
313 | CutAvator *cutter = new CutAvator(filename);
314 | cutter->setWindowFlags(Qt::WindowStaysOnTopHint|Qt::Dialog);
315 | connect(cutter,&CutAvator::cutOk,qobject_cast(this->parentWidget()->parentWidget()),&ChangeInformation::getAva);
316 | cutter->exec();
317 | cutter->deleteLater();
318 | }
319 | }
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
--------------------------------------------------------------------------------
/user/user/changeinformation.h:
--------------------------------------------------------------------------------
1 | #ifndef CHANGEINFORMATION_H
2 | #define CHANGEINFORMATION_H
3 |
4 | #include "qlineedit.h"
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | namespace Ui {
15 | class ChangeInformation;
16 | }
17 |
18 |
19 | struct MyAccountInfo {
20 | QString account;
21 | QString name;
22 | QString avator_base64;
23 | QString gender;
24 | QString signature;
25 | };
26 |
27 |
28 | class ChangeInformation : public QDialog
29 | {
30 | Q_OBJECT
31 |
32 | public:
33 | explicit ChangeInformation(MyAccountInfo info, QWidget *parent = nullptr);
34 | ~ChangeInformation();
35 | void paintEvent(QPaintEvent *event);//窗口背景
36 | void mousePressEvent(QMouseEvent *event);//捕获鼠标按下事件
37 | void mouseMoveEvent(QMouseEvent *event);//实现拖拽移动效果与调整大小效果
38 | void mouseReleaseEvent(QMouseEvent *event);//重置移动状态
39 | QString pixmapToBase64(const QPixmap &pixmap);//图片转换成base64格式
40 | QPixmap base64ToPixmap(const QString &base64Str);//将base64转换为图片
41 | void setMessage(const MyAccountInfo &info);//设置当前页面各信息
42 | void judgeMessage();//判断能否点击确认
43 |
44 | private slots:
45 | void on_but_cancelwindow_clicked();//关闭窗口
46 | void on_but_no_clicked();//点击取消 也关闭窗口
47 | void on_cbbox_sex_currentIndexChanged(int index);//改变性别 判断能否点击确认
48 | void on_line_nickname_textChanged(const QString &arg1);//昵称文本框文字改变 判断是否能点击确认
49 | void on_line_sig_textChanged(const QString &arg1);//个性签名文本框改变 判断是否能点击确认
50 | void on_but_yes_clicked();//发送修改申请
51 |
52 | public slots:
53 | void getAva(const QPixmap &pixmap);//子窗口剪切好头像 收到头像 更新并判断能否点击确认
54 | void dealResult(const QJsonObject &json);//处理修改资料的结果
55 |
56 | signals:
57 | void customClose();//告诉主窗口要关闭了
58 | void sendMessage(const MyAccountInfo& info);//告诉主窗口 发送新的信息
59 |
60 | private:
61 | Ui::ChangeInformation *ui;
62 | MyAccountInfo actInfo; // 存储账号信息
63 | QPoint dragPosition;
64 | int moveFlag = 0;
65 | int avaFlag = 0;//判断头像是不是更新过
66 | };
67 |
68 |
69 | class LineMessage:public QLineEdit//输入框类
70 | {
71 | Q_OBJECT
72 |
73 | public:
74 | LineMessage(QWidget *parent = nullptr) : QLineEdit(parent) {}
75 |
76 | public slots:
77 | void focusInEvent(QFocusEvent *event);//获得焦点处理事件
78 | void focusOutEvent(QFocusEvent *event);//失去焦点处理事件
79 |
80 | private:
81 | int flag = 0;//标记是不是第一次点击
82 | };
83 |
84 |
85 | class LabelChooseAva:public QLabel//点击头像更换头像
86 | {
87 | Q_OBJECT
88 |
89 | public:
90 | LabelChooseAva(QWidget *parent=nullptr):QLabel(parent){}
91 | void mousePressEvent(QMouseEvent *event);//点击头像更换头像
92 | };
93 | #endif // CHANGEINFORMATION_H
94 |
--------------------------------------------------------------------------------
/user/user/changepassword.cpp:
--------------------------------------------------------------------------------
1 | #include "changepassword.h"
2 | #include "ui_changepassword.h"
3 | #include "dialog.h"
4 |
5 | ChangePassword::ChangePassword(QWidget *parent)
6 | : QDialog(parent)
7 | , ui(new Ui::ChangePassword)
8 | {
9 | ui->setupUi(this);
10 | //初始化窗口
11 | QIcon icon(":/pictures/suliao.png");
12 | setWindowIcon(icon);
13 | setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
14 | setAttribute(Qt::WA_TranslucentBackground);
15 | // 将窗口居中显示
16 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
17 | if (topLevelParent) {
18 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
19 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
20 | move(x, y);
21 | }
22 | }
23 |
24 |
25 | ChangePassword::~ChangePassword()
26 | {
27 | delete ui;
28 | }
29 |
30 |
31 | void ChangePassword::setVal()//设置输入验证器
32 | {
33 | QRegularExpression regExp("^[a-zA-Z0-9]{1,12}$");//给输入框设置验证器
34 | validator = new QRegularExpressionValidator(regExp, this);
35 | ui->line_account->setValidator(validator);
36 | ui->line_password->setValidator(validator);
37 | ui->line_newpassword->setValidator(validator);
38 | ui->line_newpassword2->setValidator(validator);
39 | }
40 |
41 |
42 | void ChangePassword::paintEvent(QPaintEvent *event)//窗口背景
43 | {
44 | //调用基类方法以处理父类的绘图
45 | QDialog::paintEvent(event);
46 | QPainter painter(this);
47 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
48 | //加载背景图片
49 | QPixmap background(":/pictures/094 Cloudy Apple - trans.png");
50 | //确保图片已加载
51 | if (background.isNull()) {
52 | qWarning("背景图像加载失败");
53 | return;
54 | }
55 | QSize newSize = QSize(this->width(), this->height());
56 | //将背景图缩放为新的大小
57 | QPixmap scaledBackground = background.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
58 | //计算绘制的位置,保持居中
59 | int x = (this->width() - scaledBackground.width()) / 2;
60 | int y = (this->height() - scaledBackground.height()) / 2;
61 | //设置剪裁区域以适应圆角窗口
62 | int radius = 10;
63 | QPainterPath path;
64 | path.addRoundedRect(rect(), radius, radius);
65 | painter.setClipPath(path);
66 | //绘制背景图片
67 | painter.drawPixmap(x, y, scaledBackground);
68 | //绘制边框
69 | painter.setPen(QPen(Qt::gray, 3.5));
70 | painter.drawRoundedRect(rect(), radius, radius);
71 | }
72 |
73 |
74 | void ChangePassword::mousePressEvent(QMouseEvent *event)//捕获鼠标按下事件
75 | {
76 | //清除焦点
77 | QList widgets = this->findChildren();
78 | for (QWidget* widget : widgets) {
79 | widget->clearFocus();
80 | }
81 | QPoint pos = event->pos();
82 | int margin = 30;
83 | if (pos.x() <= 30 || pos.x() >= width() - 30 ||
84 | pos.y() <= 30 || pos.y() >= height() - 30){//如果点击在边缘
85 | qDebug() << "点击在边缘";
86 | moveFlag = 1;
87 | dragPosition = event->globalPosition().toPoint() - this->frameGeometry().topLeft();//记录鼠标相对于窗口的初始偏移
88 | event->accept();
89 | }
90 | }
91 |
92 |
93 | void ChangePassword::mouseMoveEvent(QMouseEvent *event)//实现拖拽移动效果与调整大小效果
94 | {
95 | qDebug()<<"鼠标位移了";
96 | QPoint globalPos = event->globalPosition().toPoint();//获取当前的鼠标位置
97 | QPoint delta = globalPos - (this->frameGeometry().topLeft() + dragPosition);//计算当前鼠标位置与窗口之间的相对偏移
98 | if (event->buttons() & Qt::LeftButton) {
99 | if (moveFlag == 1) {
100 | this->move(globalPos - dragPosition);
101 | event->accept();
102 | }
103 | //更新拖动位置
104 | dragPosition = globalPos - this->frameGeometry().topLeft();
105 | }
106 | }
107 |
108 |
109 | void ChangePassword::mouseReleaseEvent(QMouseEvent *event)//重置移动状态
110 | {
111 | moveFlag = 0;
112 | }
113 |
114 |
115 | void ChangePassword:: closeEvent(QCloseEvent *event)//关闭窗口事件
116 | {
117 | emit customClose();//this->disconnect();放在主窗口的槽函数了
118 | this->deleteLater();
119 | event->accept();
120 | }
121 |
122 |
123 | void ChangePassword::on_but_deletewindow_clicked()//关闭按钮
124 | {
125 | this->close();
126 | }
127 |
128 |
129 | void ChangePassword::on_line_account_textChanged(const QString &arg1)
130 | {
131 | if(ui->line_account->text() != "" && ui->line_account->text() != "请输入您的账号"
132 | && ui->line_password->text() != "" && ui->line_password->text() != "请输入您的密码"){
133 | ui->but_yes->setEnabled(true);
134 | ui->but_yes->setStyleSheet(
135 | "QPushButton {"
136 | "font: 12pt 'Microsoft YaHei UI';"
137 | "background-color: rgb(5, 186, 251);"
138 | "color: white;"
139 | "border-radius: 10px;"
140 | "border: 0.5px solid rgb(220, 220, 220);"
141 | "}"
142 | "QPushButton:hover {"
143 | "background-color: rgba(5, 186, 251, 0.7);"
144 | "color: white;"
145 | "border-radius: 10px;"
146 | "}"
147 | "QPushButton:pressed {"
148 | "background-color: rgba(0, 123, 255, 0.8);"
149 | "color: rgba(255, 255, 255, 0.9);"
150 | "border-radius: 10px;"
151 | "}"
152 | );
153 | }
154 | else{
155 | ui->but_yes->setEnabled(false);
156 | ui->but_yes->setStyleSheet(
157 | "QPushButton {"
158 | "font: 12pt 'Microsoft YaHei UI';"
159 | "background-color: rgb(167, 214, 255); "
160 | "color: white;"
161 | "border-radius: 10px;"
162 | "}"
163 | );
164 | }
165 | }
166 |
167 |
168 | void ChangePassword::on_line_password_textChanged(const QString &arg1)//第一个页面判断能否点击确认按钮
169 | {
170 | if(ui->line_account->text() != "" && ui->line_account->text() != "请输入您的账号"
171 | && ui->line_password->text() != "" && ui->line_password->text() != "请输入您的密码"){
172 | ui->but_yes->setEnabled(true);
173 | ui->but_yes->setStyleSheet(
174 | "QPushButton {"
175 | "font: 12pt 'Microsoft YaHei UI';"
176 | "background-color: rgb(5, 186, 251);"
177 | "color: white;"
178 | "border-radius: 10px;"
179 | "border: 0.5px solid rgb(220, 220, 220);"
180 | "}"
181 | "QPushButton:hover {"
182 | "background-color: rgba(5, 186, 251, 0.7);"
183 | "color: white;"
184 | "border-radius: 10px;"
185 | "}"
186 | "QPushButton:pressed {"
187 | "background-color: rgba(0, 123, 255, 0.8);"
188 | "color: rgba(255, 255, 255, 0.9);"
189 | "border-radius: 10px;"
190 | "}"
191 | );
192 | }
193 | else{
194 | ui->but_yes->setEnabled(false);
195 | ui->but_yes->setStyleSheet(
196 | "QPushButton {"
197 | "font: 12pt 'Microsoft YaHei UI';"
198 | "background-color: rgb(167, 214, 255); "
199 | "color: white;"
200 | "border-radius: 10px;"
201 | "}"
202 | );
203 | }
204 | }
205 |
206 | void ChangePassword::on_line_newpassword_textChanged(const QString &arg1)//第二个页面判断能否点击确认按钮
207 | {
208 | if(ui->line_newpassword->text() != "" && ui->line_newpassword->text() != "请输入新的密码"
209 | && ui->line_newpassword2->text() != "" && ui->line_newpassword2->text() != "请确认您的密码"){
210 | ui->but_yes_2->setEnabled(true);
211 | ui->but_yes_2->setStyleSheet(
212 | "QPushButton {"
213 | "font: 12pt 'Microsoft YaHei UI';"
214 | "background-color: rgb(5, 186, 251);"
215 | "color: white;"
216 | "border-radius: 10px;"
217 | "border: 0.5px solid rgb(220, 220, 220);"
218 | "}"
219 | "QPushButton:hover {"
220 | "background-color: rgba(5, 186, 251, 0.7);"
221 | "color: white;"
222 | "border-radius: 10px;"
223 | "}"
224 | "QPushButton:pressed {"
225 | "background-color: rgba(0, 123, 255, 0.8);"
226 | "color: rgba(255, 255, 255, 0.9);"
227 | "border-radius: 10px;"
228 | "}"
229 | );
230 | }
231 | else{
232 | ui->but_yes_2->setEnabled(false);
233 | ui->but_yes_2->setStyleSheet(
234 | "QPushButton {"
235 | "font: 12pt 'Microsoft YaHei UI';"
236 | "background-color: rgb(167, 214, 255); "
237 | "color: white;"
238 | "border-radius: 10px;"
239 | "}"
240 | );
241 | }
242 | }
243 |
244 |
245 | void ChangePassword::on_line_newpassword2_textChanged(const QString &arg1)//第二个页面判断能否点击确认按钮
246 | {
247 | if(ui->line_newpassword->text() != "" && ui->line_newpassword->text() != "请输入新的密码"
248 | && ui->line_newpassword2->text() != "" && ui->line_newpassword2->text() != "请确认您的密码"){
249 | ui->but_yes_2->setEnabled(true);
250 | ui->but_yes_2->setStyleSheet(
251 | "QPushButton {"
252 | "font: 12pt 'Microsoft YaHei UI';"
253 | "background-color: rgb(5, 186, 251);"
254 | "color: white;"
255 | "border-radius: 10px;"
256 | "border: 0.5px solid rgb(220, 220, 220);"
257 | "}"
258 | "QPushButton:hover {"
259 | "background-color: rgba(5, 186, 251, 0.7);"
260 | "color: white;"
261 | "border-radius: 10px;"
262 | "}"
263 | "QPushButton:pressed {"
264 | "background-color: rgba(0, 123, 255, 0.8);"
265 | "color: rgba(255, 255, 255, 0.9);"
266 | "border-radius: 10px;"
267 | "}"
268 | );
269 | }
270 | else{
271 | ui->but_yes_2->setEnabled(false);
272 | ui->but_yes_2->setStyleSheet(
273 | "QPushButton {"
274 | "font: 12pt 'Microsoft YaHei UI';"
275 | "background-color: rgb(167, 214, 255); "
276 | "color: white;"
277 | "border-radius: 10px;"
278 | "}"
279 | );
280 | }
281 | }
282 |
283 |
284 | void ChangePassword::on_but_yes_clicked()//告知主窗体发送账号密码
285 | {
286 | QJsonObject jsonObj;
287 | jsonObj["tag"] = "changepassword1";
288 | jsonObj["account"] = ui->line_account->text();
289 | jsonObj["password"] = ui->line_password->text();
290 | emit changePassword1(jsonObj);
291 | ui->line_account->setEnabled(false);
292 | ui->line_password->setEnabled(false);
293 | ui->but_yes->setEnabled(false);
294 | }
295 |
296 |
297 | void ChangePassword::on_but_yes_2_clicked()//告知主窗体发送修改密码
298 | {
299 | if(ui->line_newpassword->text() != ui->line_newpassword2->text()){
300 | QString text = "您的两次密码不一致。";
301 | Dialog* dialog = new Dialog(this);
302 | dialog->transText(text);
303 | dialog->exec();
304 | return;
305 | }
306 | QJsonObject jsonObj;
307 | jsonObj["tag"] = "changepassword2";
308 | jsonObj["account"] = ui->line_account->text();
309 | jsonObj["password"] = ui->line_newpassword->text();
310 | emit changePassword2(jsonObj);
311 | ui->line_newpassword->setEnabled(false);
312 | ui->line_newpassword2->setEnabled(false);
313 | ui->but_yes_2->setEnabled(false);
314 | }
315 |
316 |
317 | void ChangePassword::changePasswordAns1(const QJsonObject& json)//修改账号密码第一个申请的结果
318 | {
319 | if(json ["answer"] == "fail"){
320 | ui->line_account->setEnabled(true);
321 | ui->line_password->setEnabled(true);
322 | ui->but_yes->setEnabled(true);
323 | QString text = "请求失败。";
324 | Dialog* dialog = new Dialog(this);
325 | dialog->transText(text);
326 | dialog->exec();
327 | return;
328 |
329 | }
330 | else if(json ["answer"] == "user_not_found"){
331 | ui->line_account->setEnabled(true);
332 | ui->line_password->setEnabled(true);
333 | ui->but_yes->setEnabled(true);
334 | QString text = "账号或密码错误,请检查。";
335 | Dialog* dialog = new Dialog(this);
336 | dialog->transText(text);
337 | dialog->exec();
338 | return;
339 | }
340 | else if(json ["answer"] == "succeed"){
341 | ui->stackedWidget->setCurrentIndex(1);
342 | }
343 | }
344 |
345 |
346 | void ChangePassword::changePasswordAns2(const QJsonObject& json)//修改账号密码第二个申请的结果
347 | {
348 | if(json ["answer"] == "fail"){
349 | QString text = "请求失败。";
350 | Dialog* dialog = new Dialog(this);
351 | dialog->transText(text);
352 | dialog->exec();
353 | this->close();
354 | return;
355 |
356 | }
357 | else if(json ["answer"] == "succeed"){
358 | QString text = "修改成功!";
359 | Dialog* dialog = new Dialog(this);
360 | dialog->transText(text);
361 | dialog->exec();
362 | this->close();
363 | return;
364 | }
365 | }
366 |
367 |
368 | void LineChangePass::focusInEvent(QFocusEvent *event)//获得焦点处理事件
369 | {
370 | if(text() == "请输入您的账号" || text() == "请输入您的密码" || text() == "请输入新的密码" || text() == "请确认您的密码"){
371 | setText("");
372 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
373 | "border: 1px solid rgba(0, 0, 0, 0.1);"
374 | "border-radius: 8px;"
375 | "padding: 5px;"
376 | "color: black;");
377 | }
378 | if(objectName() == "line_newpassword" || objectName() == "line_newpassword2" || objectName() == "line_password"){
379 | this->setEchoMode(Password);
380 | }
381 | QLineEdit::focusInEvent(event);
382 | }
383 |
384 |
385 | void LineChangePass::focusOutEvent(QFocusEvent *event)//失去焦点处理事件
386 | {
387 | if(text() == ""){
388 | if(objectName() == "line_accont")
389 | {
390 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
391 | "border: 1px solid rgba(0, 0, 0, 0.1);"
392 | "border-radius: 8px;"
393 | "padding: 5px;"
394 | "color: grey;");
395 | setText("请输入您的账号");
396 | }
397 | if(objectName() == "line_password")
398 | {
399 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
400 | "border: 1px solid rgba(0, 0, 0, 0.1);"
401 | "border-radius: 8px;"
402 | "padding: 5px;"
403 | "color: grey;");
404 | setText("请输入您的密码");
405 | setEchoMode(Normal);
406 | }
407 | if(objectName() == "line_newpassword")
408 | {
409 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
410 | "border: 1px solid rgba(0, 0, 0, 0.1);"
411 | "border-radius: 8px;"
412 | "padding: 5px;"
413 | "color: grey;");
414 | setText("请输入新的密码");
415 | setEchoMode(Normal);
416 | }
417 | if(objectName() == "line_newpassword2")
418 | {
419 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
420 | "border: 1px solid rgba(0, 0, 0, 0.1);"
421 | "border-radius: 8px;"
422 | "padding: 5px;"
423 | "color: grey;");
424 | setText("请确认您的密码");
425 | setEchoMode(Normal);
426 | }
427 | }
428 | QLineEdit::focusOutEvent(event);
429 | }
430 |
431 |
432 |
--------------------------------------------------------------------------------
/user/user/changepassword.h:
--------------------------------------------------------------------------------
1 | #ifndef CHANGEPASSWORD_H
2 | #define CHANGEPASSWORD_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | namespace Ui {
14 | class ChangePassword;
15 | }
16 |
17 | class ChangePassword : public QDialog
18 | {
19 | Q_OBJECT
20 |
21 | public:
22 | explicit ChangePassword(QWidget *parent = nullptr);
23 | ~ChangePassword();
24 | void setVal();//设置输入验证器
25 | void paintEvent(QPaintEvent *event);//窗口背景
26 | void mousePressEvent(QMouseEvent *event);//捕获鼠标按下事件
27 | void mouseMoveEvent(QMouseEvent *event);//实现拖拽移动效果与调整大小效果
28 | void mouseReleaseEvent(QMouseEvent *event);//重置移动状态
29 | void closeEvent(QCloseEvent *event);//关闭窗口事件
30 |
31 | private slots:
32 | void on_but_deletewindow_clicked();//关闭按钮
33 | void on_line_account_textChanged(const QString &arg1);//第一个页面判断能否点击确认按钮
34 | void on_line_password_textChanged(const QString &arg1);//第一个页面判断能否点击确认按钮
35 | void on_line_newpassword_textChanged(const QString &arg1);//第二个页面判断能否点击确认按钮
36 | void on_line_newpassword2_textChanged(const QString &arg1);//第二个页面判断能否点击确认按钮
37 | void on_but_yes_clicked();//告知主窗体发送账号密码
38 | void on_but_yes_2_clicked();//告知主窗体发送修改密码
39 |
40 | public slots:
41 | void changePasswordAns1(const QJsonObject& json);//修改账号密码第一个申请的结果
42 | void changePasswordAns2(const QJsonObject& json);//修改账号密码第二个申请的结果
43 |
44 | signals:
45 | void customClose();//通知主窗体要关闭了
46 | void changePassword1(const QJsonObject &json);//告知主窗体发送修改申请
47 | void changePassword2(const QJsonObject &json);//告知主窗体发送最终修改申请
48 |
49 | private:
50 | Ui::ChangePassword *ui;
51 | int moveFlag = 0;
52 | QPoint dragPosition;
53 | QValidator *validator;
54 | };
55 |
56 |
57 | class LineChangePass:public QLineEdit//输入框类
58 | {
59 | Q_OBJECT
60 |
61 | public:
62 | LineChangePass(QWidget *parent = nullptr) : QLineEdit(parent) {}
63 |
64 | public slots:
65 | void focusInEvent(QFocusEvent *event);//获得焦点处理事件
66 | void focusOutEvent(QFocusEvent *event);//失去焦点处理事件
67 | };
68 |
69 | #endif // CHANGEPASSWORD_H
70 |
--------------------------------------------------------------------------------
/user/user/changepassword.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ChangePassword
4 |
5 |
6 |
7 | 0
8 | 0
9 | 322
10 | 217
11 |
12 |
13 |
14 | Dialog
15 |
16 |
17 | -
18 |
19 |
20 | Qt::ContextMenuPolicy::NoContextMenu
21 |
22 |
23 | border:none;
24 |
25 |
26 | 0
27 |
28 |
29 |
30 |
-
31 |
32 |
-
33 |
34 |
35 |
36 | 0
37 | 0
38 |
39 |
40 |
41 | font: 12pt "Microsoft YaHei UI";
42 | border:none;
43 | color:black;
44 |
45 |
46 |
47 | 输入账号:
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 | 0
56 | 0
57 |
58 |
59 |
60 |
61 | 224
62 | 38
63 |
64 |
65 |
66 |
67 | 224
68 | 38
69 |
70 |
71 |
72 | Qt::FocusPolicy::ClickFocus
73 |
74 |
75 | font: 12pt "Microsoft YaHei UI";
76 | border: 1px solid rgba(0, 0, 0, 0.1);
77 | border-radius: 8px;
78 | padding:5px;
79 | color:grey;
80 |
81 |
82 |
83 |
84 | 请输入您的账号
85 |
86 |
87 | 12
88 |
89 |
90 |
91 |
92 |
93 | -
94 |
95 |
-
96 |
97 |
98 |
99 | 0
100 | 0
101 |
102 |
103 |
104 | font: 12pt "Microsoft YaHei UI";
105 | border:none;
106 | color:black;
107 |
108 |
109 |
110 | 输入密码:
111 |
112 |
113 |
114 | -
115 |
116 |
117 |
118 | 0
119 | 0
120 |
121 |
122 |
123 |
124 | 224
125 | 38
126 |
127 |
128 |
129 |
130 | 224
131 | 38
132 |
133 |
134 |
135 | Qt::FocusPolicy::ClickFocus
136 |
137 |
138 | font: 12pt "Microsoft YaHei UI";
139 | border: 1px solid rgba(0, 0, 0, 0.1);
140 | border-radius: 8px;
141 | padding:5px;
142 | color:grey;
143 |
144 |
145 |
146 |
147 | 请输入您的密码
148 |
149 |
150 | 12
151 |
152 |
153 |
154 |
155 |
156 | -
157 |
158 |
-
159 |
160 |
161 | Qt::Orientation::Horizontal
162 |
163 |
164 |
165 | 40
166 | 20
167 |
168 |
169 |
170 |
171 | -
172 |
173 |
174 | false
175 |
176 |
177 |
178 | 0
179 | 0
180 |
181 |
182 |
183 |
184 | 175
185 | 35
186 |
187 |
188 |
189 | PointingHandCursor
190 |
191 |
192 | QPushButton {
193 | font: 12pt "Microsoft YaHei UI";
194 | background-color: rgb(167, 214, 255);
195 | color: white;
196 | border-radius: 10px;
197 | }
198 |
199 |
200 |
201 | 确认
202 |
203 |
204 |
205 | -
206 |
207 |
208 | Qt::Orientation::Horizontal
209 |
210 |
211 |
212 | 40
213 | 20
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 | -
225 |
226 |
-
227 |
228 |
229 |
230 | 0
231 | 0
232 |
233 |
234 |
235 | font: 12pt "Microsoft YaHei UI";
236 | border:none;
237 | color:black;
238 |
239 |
240 |
241 | 新的密码:
242 |
243 |
244 |
245 | -
246 |
247 |
248 |
249 | 0
250 | 0
251 |
252 |
253 |
254 |
255 | 224
256 | 38
257 |
258 |
259 |
260 |
261 | 224
262 | 38
263 |
264 |
265 |
266 | Qt::FocusPolicy::ClickFocus
267 |
268 |
269 | font: 12pt "Microsoft YaHei UI";
270 | border: 1px solid rgba(0, 0, 0, 0.1);
271 | border-radius: 8px;
272 | padding:5px;
273 | color:grey;
274 |
275 |
276 |
277 |
278 | 请输入新的密码
279 |
280 |
281 | 12
282 |
283 |
284 |
285 |
286 |
287 | -
288 |
289 |
-
290 |
291 |
292 |
293 | 0
294 | 0
295 |
296 |
297 |
298 | font: 12pt "Microsoft YaHei UI";
299 | border:none;
300 | color:black;
301 |
302 |
303 |
304 | 确认密码:
305 |
306 |
307 |
308 | -
309 |
310 |
311 |
312 | 0
313 | 0
314 |
315 |
316 |
317 |
318 | 224
319 | 38
320 |
321 |
322 |
323 |
324 | 224
325 | 38
326 |
327 |
328 |
329 | Qt::FocusPolicy::ClickFocus
330 |
331 |
332 | font: 12pt "Microsoft YaHei UI";
333 | border: 1px solid rgba(0, 0, 0, 0.1);
334 | border-radius: 8px;
335 | padding:5px;
336 | color:grey;
337 |
338 |
339 |
340 |
341 | 请确认您的密码
342 |
343 |
344 | 12
345 |
346 |
347 |
348 |
349 |
350 | -
351 |
352 |
-
353 |
354 |
355 | Qt::Orientation::Horizontal
356 |
357 |
358 |
359 | 40
360 | 20
361 |
362 |
363 |
364 |
365 | -
366 |
367 |
368 | false
369 |
370 |
371 |
372 | 0
373 | 0
374 |
375 |
376 |
377 |
378 | 175
379 | 35
380 |
381 |
382 |
383 | PointingHandCursor
384 |
385 |
386 | QPushButton {
387 | font: 12pt "Microsoft YaHei UI";
388 | background-color: rgb(167, 214, 255);
389 | color: white;
390 | border-radius: 10px;
391 | }
392 |
393 |
394 |
395 | 确认
396 |
397 |
398 |
399 | -
400 |
401 |
402 | Qt::Orientation::Horizontal
403 |
404 |
405 |
406 | 40
407 | 20
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 | -
419 |
420 |
-
421 |
422 |
423 |
424 | 0
425 | 0
426 |
427 |
428 |
429 | font: 700 11pt "Microsoft YaHei UI";
430 | border:none;
431 |
432 |
433 | 修改密码
434 |
435 |
436 | Qt::AlignmentFlag::AlignCenter
437 |
438 |
439 |
440 | -
441 |
442 |
443 |
444 | 0
445 | 15
446 |
447 |
448 |
449 |
450 | 20
451 | 20
452 |
453 |
454 |
455 |
456 | 20
457 | 20
458 |
459 |
460 |
461 | QPushButton {
462 | border: none;
463 | background: transparent;
464 | color: rgb(78, 78, 78);
465 | font: 16pt 'Microsoft New Tai Lue';
466 | }
467 |
468 | QPushButton:hover {
469 | border: none;
470 | background: transparent;
471 | color: white;
472 | font: 16pt 'Microsoft New Tai Lue';
473 | background: red;
474 | border-radius: 3px;
475 | }
476 |
477 |
478 | x
479 |
480 |
481 | false
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 | LineChangePass
492 | QLineEdit
493 |
494 |
495 |
496 |
497 |
498 |
499 |
--------------------------------------------------------------------------------
/user/user/choicedialog.cpp:
--------------------------------------------------------------------------------
1 | #include "choicedialog.h"
2 | #include "ui_choicedialog.h"
3 | #include "autocleartextedit.h"
4 |
5 | ChoiceDialog::ChoiceDialog(QWidget *parent)
6 | : QDialog(parent)
7 | , ui(new Ui::ChoiceDialog)
8 | {
9 | ui->setupUi(this);
10 | //初始化窗口
11 | QIcon icon(":/pictures/suliao.png");//初始化窗口
12 | setWindowIcon(icon);
13 | setWindowFlags( Qt::FramelessWindowHint | Qt::Dialog);
14 | setAttribute(Qt::WA_TranslucentBackground);//允许背景透明
15 | //设置文本框
16 | setEdit();
17 | // 连接按钮的点击信号
18 | connect(ui->but_yes, &QPushButton::clicked, this, &ChoiceDialog::reject);
19 | connect(ui->but_no, &QPushButton::clicked, this, &ChoiceDialog::accept);
20 | // 将窗口居中显示
21 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
22 | if (topLevelParent) {
23 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
24 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
25 | move(x, y);
26 | }
27 | }
28 |
29 |
30 | ChoiceDialog::~ChoiceDialog()
31 | {
32 | delete ui;
33 | }
34 |
35 |
36 | void ChoiceDialog::setEdit()//设置文本框
37 | {
38 | ui->textEdit_notice->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用垂直滚动条
39 | ui->textEdit_notice->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用水平滚动条
40 | ui->textEdit_notice->setReadOnly(true);//设置为只读
41 | ui->textEdit_notice->setAlignment(Qt::AlignCenter);
42 | }
43 |
44 |
45 | void ChoiceDialog::paintEvent(QPaintEvent *event)//窗口背景
46 | {
47 | //调用基类方法以处理父类的绘图
48 | QDialog::paintEvent(event);
49 | QPainter painter(this);
50 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
51 | //设置圆角半径
52 | int radius = 4;//圆角半径
53 | //设置背景颜色
54 | painter.setBrush(QBrush(QColor(255, 255, 255)));
55 | //绘制圆角矩形背景
56 | painter.drawRoundedRect(rect(), radius, radius);
57 | }
58 |
59 |
60 | void ChoiceDialog::transText(QString text)//改变文字
61 | {
62 | //设置 textEdit_notice 的文本
63 | ui->textEdit_notice->setText(text);
64 | ui->textEdit_notice->setAlignment(Qt::AlignCenter);
65 | }
66 |
67 |
68 | void ChoiceDialog::transButText(QString no, QString yes)//改变按钮文字
69 | {
70 | ui->but_no->setText(no);
71 | ui->but_yes->setText(yes);
72 | }
73 |
74 |
75 | void ChoiceDialog::on_but_yes_clicked()//确认
76 | {
77 | close();
78 | }
79 |
80 |
81 | void ChoiceDialog::on_but_no_clicked()//取消
82 | {
83 | close();
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/user/user/choicedialog.h:
--------------------------------------------------------------------------------
1 | #ifndef CHOICEDIALOG_H
2 | #define CHOICEDIALOG_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace Ui {
9 | class ChoiceDialog;
10 | }
11 |
12 | class ChoiceDialog : public QDialog
13 | {
14 | Q_OBJECT
15 |
16 | public:
17 | explicit ChoiceDialog(QWidget *parent = nullptr);
18 | ~ChoiceDialog();
19 | void setEdit();//设置文本框
20 | void paintEvent(QPaintEvent *event);//窗口背景
21 | void transText(QString text);//改变文字
22 | void transButText(QString no, QString yes);//改变按钮文字
23 |
24 | private slots:
25 | void on_but_yes_clicked();//确认
26 | void on_but_no_clicked();//取消
27 |
28 | private:
29 | Ui::ChoiceDialog *ui;
30 | };
31 |
32 | #endif // CHOICEDIALOG_H
33 |
--------------------------------------------------------------------------------
/user/user/choicedialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ChoiceDialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 247
10 | 142
11 |
12 |
13 |
14 | Dialog
15 |
16 |
17 | -
18 |
19 |
20 | Qt::ContextMenuPolicy::NoContextMenu
21 |
22 |
23 | border:none;
24 | font: 12pt "Microsoft YaHei UI";
25 | padding:5px;
26 | background:transparent;
27 |
28 |
29 |
30 | -
31 |
32 |
33 |
34 | 0
35 | 0
36 |
37 |
38 |
39 |
40 | 0
41 | 30
42 |
43 |
44 |
45 | PointingHandCursor
46 |
47 |
48 | Qt::ContextMenuPolicy::NoContextMenu
49 |
50 |
51 | QPushButton {
52 | font: 13pt 'Microsoft YaHei UI';
53 | background-color: rgb(238, 238, 238);
54 | color: black;
55 | border:none;
56 | border-radius: 5px;
57 | }
58 | QPushButton:hover {
59 | background-color: rgb(225, 225, 225);
60 | color: red;
61 | border-radius: 5px;
62 | }
63 | QPushButton:pressed {
64 | background-color: rgb(206, 206, 206);
65 | color: red;
66 | border-radius: 5px;
67 | }
68 |
69 |
70 | 确定
71 |
72 |
73 |
74 | -
75 |
76 |
77 |
78 | 0
79 | 0
80 |
81 |
82 |
83 |
84 | 0
85 | 30
86 |
87 |
88 |
89 | PointingHandCursor
90 |
91 |
92 | Qt::ContextMenuPolicy::NoContextMenu
93 |
94 |
95 | QPushButton {
96 | font: 13pt 'Microsoft YaHei UI';
97 | background-color: rgb(238, 238, 238);
98 | color: black;
99 | border:none;
100 | border-radius: 5px;
101 | }
102 | QPushButton:hover {
103 | background-color: rgb(225, 225, 225);
104 | color: black;
105 | border-radius: 5px;
106 | }
107 | QPushButton:pressed {
108 | background-color: rgb(206, 206, 206);
109 | color: black;
110 | border-radius: 5px;
111 | }
112 |
113 |
114 | 取消
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | AutoClearTextEdit
123 | QTextEdit
124 |
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/user/user/cutavator.cpp:
--------------------------------------------------------------------------------
1 | #include "cutavator.h"
2 | #include "ui_cutavator.h"
3 | #include "registerwindow.h"
4 |
5 | CutAvator::CutAvator(const QString &mypath,QWidget *parent)
6 | : QDialog(parent),ui(new Ui::CutAvator)
7 | , path(mypath)
8 | {
9 | ui->setupUi(this);
10 | //处理传入的图片,确保它是有效的
11 | dealImage(mypath);
12 | //先截一次 防止图片格式出错
13 | on_but_cut_clicked();
14 | //连接截取框信号槽
15 | connect(ui->lab_cut, &DraggableResizableLabel::labelMoved, this, &CutAvator::moveRect);
16 | ui->lab_cut->resize(277,277);
17 | // 将窗口居中显示
18 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
19 | if (topLevelParent) {
20 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
21 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
22 | move(x, y);
23 | }
24 | }
25 |
26 |
27 | CutAvator::~CutAvator()
28 | {
29 | delete ui;
30 | delete labelRect;
31 | }
32 |
33 |
34 | void CutAvator::dealImage(QString path)//处理传入的图片
35 | {
36 | QImage image(path);
37 | if (image.isNull()) {
38 | QMessageBox msgBox;
39 | QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
40 | msgBox.setIcon(QMessageBox::Critical);
41 | msgBox.setWindowIcon(icon);
42 | msgBox.setWindowTitle("加载失败");
43 | msgBox.setText("您的图片有问题!");
44 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog);
45 | msgBox.exec();
46 | return;
47 | }
48 | image = image.convertToFormat(QImage::Format_ARGB32);//避免透明度问题
49 | path = "saved_background_image.png";
50 | image.save(path, "PNG");//保存为PNG格式
51 | setBackground(path);
52 | }
53 |
54 |
55 | void CutAvator::paintEvent(QPaintEvent *event)//初始化整个窗口背景
56 | {
57 | QPainter painter(this);
58 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
59 | QPixmap pixmap(":/pictures/094 Cloudy Apple - trans.png");
60 | painter.drawPixmap(0, 0, width(), height(), pixmap);
61 | QIcon icon(":/pictures/suliao.png");
62 | setWindowIcon(icon);
63 | }
64 |
65 |
66 | void CutAvator::setBackground(QString avapath)//设置头像
67 | {
68 | QPixmap originalPixMap(avapath);
69 | QSize targetSize(277, 300);//子窗口大小
70 | QSize maxSize(277, 277);//最大图片尺寸
71 | QPixmap scaledPixMap = originalPixMap.scaled(maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
72 | QPixmap resultPixMap(targetSize);
73 | QPainter painter(&resultPixMap);
74 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
75 | painter.fillRect(resultPixMap.rect(), QColor(255, 255, 255, 255));//背景为白色
76 | //计算居中绘制位置
77 | int x = (targetSize.width() - scaledPixMap.width()) / 2;
78 | int y = (targetSize.height() - scaledPixMap.height()) / 2 + 11.5;
79 | painter.drawPixmap(x, y, scaledPixMap);
80 | //计算 labelRect 的位置
81 | if (flag > 0) {
82 | delete labelRect;
83 | labelRect = nullptr;
84 | flag--;
85 | }
86 | CutAvator::labelRect = new QRect(ui->lab_cut->geometry());
87 | flag++;
88 | //计算全局位置
89 | QPoint globalPos = ui->lab_cut->mapToGlobal(QPoint(0, 0)) + QPoint(0, 23);
90 | labelRect->moveTopLeft(globalPos);
91 | //保存 labelRect 区域的背景
92 | QPixmap backgroundPixmap(resultPixMap.copy(*labelRect));
93 | //绘制半透明层
94 | painter.fillRect(resultPixMap.rect(), QColor(0, 0, 0, 128));
95 | //在矩形区域内恢复背景
96 | painter.drawPixmap(labelRect->topLeft(), backgroundPixmap);
97 | //绘制 labelRect 边框
98 | painter.setPen(QColor(0, 0, 0));//黑色边框
99 | painter.drawRect(*labelRect);
100 | //设置调色板应用背景图
101 | QPalette palette;
102 | palette.setBrush(QPalette::Window, resultPixMap);
103 | ui->dock_avator->setAutoFillBackground(true);
104 | ui->dock_avator->setPalette(palette);
105 | ui->dock_avator->setFeatures(QDockWidget::NoDockWidgetFeatures);
106 | }
107 |
108 |
109 | void CutAvator::moveRect(const QPoint &newPosition)//移动明亮矩形更新头像
110 | {
111 | QSize targetSize(277, 300);//子窗口大小
112 | QSize maxSize(277, 277);//最大图片尺寸
113 | QPixmap originalPixMap(path);
114 | QPixmap scaledPixMap = originalPixMap.scaled(maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
115 | QPixmap resultPixMap(targetSize);
116 | QPainter painter(&resultPixMap);
117 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
118 | painter.fillRect(resultPixMap.rect(), QColor(255, 255, 255, 255));//背景为白色
119 | //更新 labelRect 的大小以匹配 ui->lab_cut
120 | QSize newSize = ui->lab_cut->size();
121 | labelRect->setSize(newSize);
122 | labelRect->moveTopLeft(newPosition + QPoint(0, 23));
123 | //计算居中绘制位置
124 | int x = (targetSize.width() - scaledPixMap.width()) / 2;
125 | int y = (targetSize.height() - scaledPixMap.height()) / 2 + 11.5;
126 | painter.drawPixmap(x, y, scaledPixMap);
127 | //保存 labelRect 区域的背景
128 | QPixmap backgroundPixmap(resultPixMap.copy(*labelRect));
129 | //绘制半透明层
130 | painter.fillRect(resultPixMap.rect(), QColor(0, 0, 0, 128));
131 | //在矩形区域内恢复背景
132 | painter.drawPixmap(labelRect->topLeft(), backgroundPixmap);
133 | //绘制 labelRect 边框
134 | painter.setPen(QColor(0, 0, 0, 0));//黑色边框
135 | painter.drawRect(*labelRect);
136 | //更新调色板以使用新的背景图像
137 | QPalette palette;
138 | palette.setBrush(QPalette::Window, resultPixMap);
139 | ui->dock_avator->setPalette(palette);
140 | }
141 |
142 |
143 | void CutAvator::on_but_cut_clicked()//点击后剪裁头像
144 | {
145 | ui->lab_cut->setVisible(false);//防止截到边框黑边
146 | //获取dock窗口的背景并拉伸
147 | QPixmap dockPixmap = ui->dock_avator->grab();
148 | QPixmap dockPixmapResize = dockPixmap.scaled(277, 300,
149 | Qt::KeepAspectRatio, Qt::SmoothTransformation);
150 | //获取 lab_cut 在 dock_avator 中的位置和大小
151 | QRect cutrect = ui->lab_cut->geometry();//获取位置和大小
152 | QPoint cutPosInDock = ui->lab_cut->mapTo(ui->dock_avator, QPoint(0, 0));
153 | cutrect.moveTo(cutPosInDock);//移动到 dock_avator 的坐标
154 | //确保 cutrect 在 dockpixmap_resize 内
155 | cutrect.intersects(QRect(0, 0, dockPixmapResize.width(), dockPixmapResize.height()));
156 | //从调整大小后的 dockpixmap 中复制对应的区域
157 | QPixmap finalpixmap = dockPixmapResize.copy(cutrect);
158 | finalpixmap.save("saved_background_image.png", "PNG");
159 | path = "saved_background_image.png";
160 | moveRect(ui->lab_cut->mapToParent(QPoint(0, 0)));
161 | ui->lab_cut->setVisible(true);
162 | }
163 |
164 |
165 | void CutAvator::on_but_yes_clicked()//上传头像并关闭窗口
166 | {
167 | emit cutOk(path);
168 | close();
169 | }
170 |
171 |
172 | void DraggableResizableLabel::mousePressEvent(QMouseEvent *event)//点击判断是要干什么
173 | {
174 | if (event->button() == Qt::LeftButton)
175 | {
176 | myOffset = event->pos();
177 | myResizing = (event->pos().x() > width() - 10 && event->pos().y() > height() - 10);
178 | }
179 | }
180 |
181 |
182 | void DraggableResizableLabel::mouseMoveEvent(QMouseEvent *event)//移动时判断是移动还是变动大小
183 | {
184 | //检测鼠标是否在右下角区域
185 | if (event->pos().x() > width() - 10 && event->pos().y() > height() - 10)
186 | {
187 | setCursor(Qt::SizeFDiagCursor);//设置光标为调整大小
188 | myResizing = true;
189 | }
190 | else
191 | {
192 | setCursor(Qt::ArrowCursor);//设置光标为箭头
193 | myResizing = false;
194 | }
195 | if (event->buttons() & Qt::LeftButton)
196 | {
197 | if (myResizing)
198 | {
199 | //调整大小,保持正方形
200 | int newSize = qMax(50, qMin(event->pos().x(), event->pos().y()));
201 | QRect parentRect = parentWidget()->rect();
202 | //确保新大小不超出父窗口的尺寸
203 | int maxWidth = parentRect.width() - pos().x();
204 | int maxHeight = parentRect.height() - pos().y();
205 | newSize = qMin(newSize, qMin(maxWidth, maxHeight));
206 | setFixedSize(newSize, newSize);
207 | emit labelMoved(mapToParent(QPoint(0, 0)));//发送当前标签的位置
208 | }
209 | else
210 | {
211 | //移动标签
212 | QPoint newPosition = mapToParent(event->pos() - myOffset);
213 | //限制移动范围,确保不超出父窗口
214 | QRect parentRect = parentWidget()->rect();
215 | QSize labelSize = size();
216 | newPosition.setX(qMax(parentRect.left(), qMin(newPosition.x(), parentRect.right() - labelSize.width())));
217 | newPosition.setY(qMax(parentRect.top(), qMin(newPosition.y(), parentRect.bottom() - labelSize.height())));
218 |
219 | move(newPosition);
220 | emit labelMoved(newPosition);//发送新位置
221 | }
222 | }
223 | }
224 |
225 |
226 | void DraggableResizableLabel::mouseReleaseEvent(QMouseEvent *event)//释放重置状态
227 | {
228 | Q_UNUSED(event);
229 | myResizing = false;//重置状态
230 | unsetCursor();//恢复光标
231 | }
232 |
233 |
--------------------------------------------------------------------------------
/user/user/cutavator.h:
--------------------------------------------------------------------------------
1 | #ifndef CUTAVATOR_H
2 | #define CUTAVATOR_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | namespace Ui {
18 | class CutAvator;
19 | }
20 |
21 |
22 | class CutAvator : public QDialog
23 | {
24 | Q_OBJECT
25 |
26 | public:
27 | explicit CutAvator(const QString &mypath,QWidget *parent = nullptr);
28 | ~CutAvator();
29 | void dealImage(QString path);//处理传入的图片
30 | void paintEvent(QPaintEvent *event);//初始化整个窗口背景
31 | void setBackground(QString avapath);//设置头像
32 |
33 | public slots:
34 | void moveRect(const QPoint &newPosition);//移动明亮矩形更新头像
35 |
36 | signals:
37 | void cutOk(const QPixmap &pixmap);//裁剪完了发送信号
38 |
39 | private slots:
40 | void on_but_cut_clicked();//点击后剪裁头像
41 | void on_but_yes_clicked();//点击后上传头像并关闭窗口
42 |
43 | private:
44 | Ui::CutAvator *ui;
45 | QString path;
46 | QRect *labelRect;
47 | QPainter painter;
48 | int flag = 0;
49 | };
50 |
51 | class DraggableResizableLabel : public QLabel
52 | {
53 | Q_OBJECT
54 | public:
55 | explicit DraggableResizableLabel(QWidget *parent = nullptr) : QLabel(parent)
56 | {}
57 |
58 | signals:
59 | void labelMoved(const QPoint &newPosition);//标签发生任何变化时发送信号
60 |
61 | protected:
62 | void mousePressEvent(QMouseEvent *event) override;//点击判断是要干什么
63 | void mouseMoveEvent(QMouseEvent *event) override;//移动时判断是移动还是变动大小
64 | void mouseReleaseEvent(QMouseEvent *event) override;//释放重置状态
65 |
66 | private:
67 | QPoint myOffset;
68 | bool myResizing = false;//标志是否正在调整大小
69 | };
70 |
71 | #endif // CUTAVATOR_H
72 |
--------------------------------------------------------------------------------
/user/user/cutavator.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | CutAvator
4 |
5 |
6 |
7 | 0
8 | 0
9 | 394
10 | 376
11 |
12 |
13 |
14 |
15 | 0
16 | 0
17 |
18 |
19 |
20 |
21 | 311
22 | 311
23 |
24 |
25 |
26 |
27 | 900
28 | 900
29 |
30 |
31 |
32 | Qt::ContextMenuPolicy::NoContextMenu
33 |
34 |
35 | 编辑头像
36 |
37 |
38 | -
39 |
40 |
-
41 |
42 |
43 | Qt::Orientation::Horizontal
44 |
45 |
46 |
47 | 40
48 | 20
49 |
50 |
51 |
52 |
53 | -
54 |
55 |
56 |
57 | 0
58 | 0
59 |
60 |
61 |
62 |
63 | 80
64 | 30
65 |
66 |
67 |
68 | PointingHandCursor
69 |
70 |
71 | Qt::ContextMenuPolicy::NoContextMenu
72 |
73 |
74 | QPushButton {
75 | font: 12pt 'Microsoft YaHei UI';
76 | background-color: rgb(5, 186, 251);
77 | color: white;
78 | border-radius: 10px;
79 | }
80 |
81 | QPushButton:hover {
82 | background-color: rgba(5, 186, 251, 0.7);
83 | color: white;
84 | border-radius: 10px;
85 | }
86 |
87 | QPushButton:pressed {
88 | background-color: rgba(0, 123, 255, 0.8);
89 | color: rgba(255, 255, 255, 0.9);
90 | border-radius: 10px;
91 | }
92 |
93 |
94 | 裁剪
95 |
96 |
97 |
98 | -
99 |
100 |
101 |
102 | 0
103 | 0
104 |
105 |
106 |
107 |
108 | 80
109 | 30
110 |
111 |
112 |
113 | PointingHandCursor
114 |
115 |
116 | Qt::ContextMenuPolicy::NoContextMenu
117 |
118 |
119 | QPushButton {
120 | font: 12pt 'Microsoft YaHei UI';
121 | background-color: rgb(5, 186, 251);
122 | color: white;
123 | border-radius: 10px;
124 | }
125 |
126 | QPushButton:hover {
127 | background-color: rgba(5, 186, 251, 0.7);
128 | color: white;
129 | border-radius: 10px;
130 | }
131 |
132 | QPushButton:pressed {
133 | background-color: rgba(0, 123, 255, 0.8);
134 | color: rgba(255, 255, 255, 0.9);
135 | border-radius: 10px;
136 | }
137 |
138 |
139 | 确认
140 |
141 |
142 |
143 |
144 |
145 | -
146 |
147 |
148 |
149 | 0
150 | 0
151 |
152 |
153 |
154 |
155 | 277
156 | 300
157 |
158 |
159 |
160 |
161 | 277
162 | 300
163 |
164 |
165 |
166 | QDockWidget::title {
167 | background: rgb(241, 231, 234)
168 | }
169 |
170 |
171 |
172 |
173 |
174 | 0
175 | 0
176 | 277
177 | 283
178 |
179 |
180 |
181 | border: 2px dashed rgb(0, 0, 0);
182 | color:rgb(0, 0, 127);
183 |
184 |
185 |
186 |
187 |
188 |
189 | Qt::AlignmentFlag::AlignCenter
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 | DraggableResizableLabel
200 | QLabel
201 |
202 |
203 |
204 |
205 | but_yes
206 |
207 |
208 |
209 |
210 |
--------------------------------------------------------------------------------
/user/user/dialog.cpp:
--------------------------------------------------------------------------------
1 | #include "dialog.h"
2 | #include "ui_dialog.h"
3 | #include "autocleartextedit.h"
4 |
5 | Dialog::Dialog(QWidget *parent)
6 | : QDialog(parent)
7 | , ui(new Ui::Dialog)
8 | {
9 | ui->setupUi(this);
10 | //初始化窗口
11 | QIcon icon(":/pictures/suliao.png");//初始化窗口
12 | setWindowIcon(icon);
13 | setWindowFlags( Qt::FramelessWindowHint | Qt::Dialog);
14 | setAttribute(Qt::WA_TranslucentBackground);//允许背景透明
15 | //设置文本框
16 | setEdit();
17 | // 将窗口居中显示
18 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
19 | if (topLevelParent) {
20 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
21 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
22 | move(x, y);
23 | }
24 | }
25 |
26 |
27 | Dialog::~Dialog()
28 | {
29 | delete ui;
30 | }
31 |
32 |
33 | void Dialog::setEdit()//设置文本框
34 | {
35 | ui->textEdit_notice->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用垂直滚动条
36 | ui->textEdit_notice->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用水平滚动条
37 | ui->textEdit_notice->setReadOnly(true);//设置为只读
38 | ui->textEdit_notice->setAlignment(Qt::AlignCenter);
39 | }
40 |
41 |
42 | void Dialog::paintEvent(QPaintEvent *event)//窗口背景
43 | {
44 | //调用基类方法以处理父类的绘图
45 | QDialog::paintEvent(event);
46 | QPainter painter(this);
47 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
48 | //设置圆角半径
49 | int radius = 4;//圆角半径
50 | //设置背景颜色
51 | painter.setBrush(QBrush(QColor(255, 255, 255)));
52 | //绘制圆角矩形背景
53 | painter.drawRoundedRect(rect(), radius, radius);
54 | }
55 |
56 |
57 | void Dialog::transText(QString text)//改变文字
58 | {
59 | //设置 textEdit_notice 的文本
60 | ui->textEdit_notice->setText(text);
61 | ui->textEdit_notice->setAlignment(Qt::AlignCenter);
62 | }
63 |
64 |
65 | void Dialog::on_but_delete_clicked()//点击确定关闭窗口
66 | {
67 | this->close();
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/user/user/dialog.h:
--------------------------------------------------------------------------------
1 | #ifndef DIALOG_H
2 | #define DIALOG_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace Ui {
9 | class Dialog;
10 | }
11 |
12 |
13 | class Dialog : public QDialog
14 | {
15 | Q_OBJECT
16 |
17 | public:
18 | explicit Dialog(QWidget *parent = nullptr);
19 | ~Dialog();
20 | void setEdit();//设置文本框
21 | void paintEvent(QPaintEvent *event);//窗口背景
22 | void transText(QString text);//改变文字
23 |
24 | private slots:
25 | void on_but_delete_clicked();//点击确定关闭窗口
26 |
27 | private:
28 | Ui::Dialog *ui;
29 | };
30 |
31 | #endif // DIALOG_H
32 |
--------------------------------------------------------------------------------
/user/user/dialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dialog
4 |
5 |
6 | Qt::WindowModality::WindowModal
7 |
8 |
9 |
10 | 0
11 | 0
12 | 250
13 | 140
14 |
15 |
16 |
17 | Dialog
18 |
19 |
20 | -
21 |
22 |
-
23 |
24 |
25 | Qt::Orientation::Horizontal
26 |
27 |
28 | QSizePolicy::Policy::Fixed
29 |
30 |
31 |
32 | 50
33 | 20
34 |
35 |
36 |
37 |
38 | -
39 |
40 |
41 |
42 | 0
43 | 0
44 |
45 |
46 |
47 |
48 | 0
49 | 30
50 |
51 |
52 |
53 | PointingHandCursor
54 |
55 |
56 | Qt::ContextMenuPolicy::NoContextMenu
57 |
58 |
59 | QPushButton {
60 | font: 13pt 'Microsoft YaHei UI';
61 | background-color: rgb(238, 238, 238);
62 | color: black;
63 | border:none;
64 | border-radius: 5px;
65 | }
66 | QPushButton:hover {
67 | background-color: rgb(225, 225, 225);
68 | color: black;
69 | border-radius: 5px;
70 | }
71 | QPushButton:pressed {
72 | background-color: rgb(206, 206, 206);
73 | color: black;
74 | border-radius: 5px;
75 | }
76 |
77 |
78 | 确定
79 |
80 |
81 |
82 | -
83 |
84 |
85 | Qt::Orientation::Horizontal
86 |
87 |
88 | QSizePolicy::Policy::Fixed
89 |
90 |
91 |
92 | 50
93 | 20
94 |
95 |
96 |
97 |
98 |
99 |
100 | -
101 |
102 |
-
103 |
104 |
105 | Qt::Orientation::Horizontal
106 |
107 |
108 |
109 | 13
110 | 87
111 |
112 |
113 |
114 |
115 | -
116 |
117 |
118 | Qt::ContextMenuPolicy::NoContextMenu
119 |
120 |
121 | border:none;
122 | font: 12pt "Microsoft YaHei UI";
123 | padding:5px;
124 | background:transparent;
125 |
126 |
127 |
128 | -
129 |
130 |
131 | Qt::Orientation::Horizontal
132 |
133 |
134 |
135 | 13
136 | 87
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | AutoClearTextEdit
148 | QTextEdit
149 |
150 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/user/user/findpassword.cpp:
--------------------------------------------------------------------------------
1 | #include "findpassword.h"
2 | #include "qevent.h"
3 | #include "ui_findpassword.h"
4 | #include "dialog.h"
5 |
6 | FindPassword::FindPassword(QTcpSocket* msocket,QWidget *parent)
7 | : QMainWindow(parent)
8 | , ui(new Ui::FindPassword),socket(msocket)
9 | {
10 | ui->setupUi(this);
11 | //初始化窗口
12 | setWindowFlags(Qt::Dialog);
13 | //给输入框设置验证器
14 | setVal();
15 | // 将窗口居中显示
16 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
17 | if (topLevelParent) {
18 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
19 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
20 | move(x, y);
21 | }
22 | }
23 |
24 |
25 | FindPassword::~FindPassword()
26 | {
27 | delete ui;
28 | delete validator;
29 | }
30 |
31 |
32 | void FindPassword::setVal()//给输入框设置验证器
33 | {
34 | QRegularExpression regExp("^[a-zA-Z0-9]{1,12}$");
35 | FindPassword::validator = new QRegularExpressionValidator(regExp, this);
36 | ui->line_pages1->setValidator(validator);
37 | ui->line_pages3->setValidator(validator);
38 | ui->line_pages3_2->setValidator(validator);
39 | }
40 |
41 |
42 | void FindPassword::paintEvent(QPaintEvent *event)//初始化背景
43 | {
44 | QPainter painter(this);
45 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
46 | QPixmap pixmap(":/pictures/094 Cloudy Apple - trans.png");
47 | painter.drawPixmap(0, 0, width(), height(), pixmap);
48 | }
49 |
50 |
51 | void FindPassword::closeEvent(QCloseEvent *event)//关闭窗口事件
52 | {
53 | this->disconnect();
54 | //在关闭时调用 deleteLater
55 | this->deleteLater();
56 | //接受关闭事件
57 | event->accept();
58 | }
59 |
60 |
61 | void FindPassword::mousePressEvent(QMouseEvent *event)//点击窗口空白让所有输入框失去焦点
62 | {
63 | ui->line_pages1->clearFocus();
64 | ui->line_pages2->clearFocus();
65 | ui->line_pages3->clearFocus();
66 | ui->line_pages3_2->clearFocus();
67 | }
68 |
69 |
70 | void FindPassword::on_but_pages1_clicked()//切换页面
71 | {
72 | if(socket->state() != QAbstractSocket::ConnectedState){//没连接到服务器
73 | Dialog msgBox(this);
74 | msgBox.transText("请检查您的网络连接!");
75 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
76 | msgBox.exec();
77 | return;
78 | }
79 | jsonObj = QJsonObject();
80 | jsonObj["tag"] = "findpassword1";
81 | jsonObj["qq_number"] = ui->line_pages1->text();
82 | //发送消息
83 | jsonDoc = QJsonDocument(jsonObj);
84 | jsonData = jsonDoc.toJson();
85 | //添加标识符
86 | QByteArray messageWithSeparator = jsonData + "END";
87 | //发送JSON 数据
88 | socket->write(messageWithSeparator);
89 | socket->flush();
90 | jsonData.clear();
91 | qDebug() << "发送要找回的账号了";
92 | }
93 |
94 |
95 | void FindPassword::on_but_pages2_clicked()//切换页面
96 | {
97 | if(socket->state() != QAbstractSocket::ConnectedState){//没连接到服务器
98 | Dialog msgBox(this);
99 | msgBox.transText("请检查您的网络连接!");
100 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
101 | msgBox.exec();
102 | return;
103 | }
104 | jsonObj = QJsonObject();
105 | jsonObj["tag"] = "findpassword2";
106 | jsonObj["qq_number"] = ui->line_pages1->text();
107 | jsonObj["theanswer"] = ui->line_pages2->text();
108 | //发送消息
109 | jsonDoc = QJsonDocument(jsonObj);
110 | jsonData = jsonDoc.toJson();
111 | //添加标识符
112 | QByteArray messageWithSeparator = jsonData + "END";
113 | //发送JSON 数据
114 | socket->write(messageWithSeparator);
115 | socket->flush();
116 | jsonData.clear();
117 | qDebug() << "发送密保答案了"<state() != QAbstractSocket::ConnectedState){//没连接到服务器
124 | Dialog msgBox(this);
125 | msgBox.transText("请检查您的网络连接!");
126 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
127 | msgBox.exec();
128 | return;
129 | }
130 | if(ui->line_pages3->text() != ui->line_pages3_2->text()){
131 | Dialog msgBox(this);
132 | msgBox.transText("您的两次密码不一致!");
133 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
134 | msgBox.exec();
135 | return;
136 | }
137 | jsonObj = QJsonObject();
138 | jsonObj["tag"] = "findpassword3";
139 | jsonObj["qq_number"]= ui->line_pages1->text();
140 | jsonObj["password"] = ui->line_pages3_2->text();
141 | //发送消息
142 | jsonDoc = QJsonDocument(jsonObj);
143 | jsonData = jsonDoc.toJson();
144 | //添加标识符
145 | QByteArray messageWithSeparator = jsonData + "END";
146 | //发送JSON 数据
147 | socket->write(messageWithSeparator);
148 | socket->flush();
149 | jsonData.clear();
150 | qDebug() << "发送修改后的密码了"<page_find->setCurrentIndex(1);
164 | ui->lab_pages2->setText(jsonObj["question"].toString());
165 | }
166 | }
167 |
168 |
169 | void FindPassword::findPassword2(const QJsonObject &jsonObj)//看看问题回答对了没有 对应切换页面或弹窗
170 | {
171 | if(jsonObj["answer"] == "no"){
172 | Dialog msgBox(this);
173 | msgBox.transText("您的答案不正确!");
174 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
175 | msgBox.exec();
176 | }
177 | if(jsonObj["answer"] == "yes"){
178 | ui->page_find->setCurrentIndex(2);
179 | }
180 | }
181 |
182 |
183 | void FindPassword::findPassword3(const QJsonObject &jsonObj)//修改密码成功没有 对应弹窗
184 | {
185 | if(jsonObj["answer"] == "no"){
186 | Dialog msgBox(this);
187 | msgBox.transText("请求失败!");
188 | msgBox.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
189 | msgBox.exec();
190 | }
191 | if(jsonObj["answer"] == "yes"){
192 | QString text = "找回密码成功";
193 | Dialog* dialog = new Dialog(this);
194 | dialog->transText(text);
195 | dialog->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog |Qt::FramelessWindowHint);
196 | dialog->exec();
197 | this->disconnect();
198 | this->close();
199 | }
200 | }
201 |
202 |
203 | void LineFind::focusInEvent(QFocusEvent *event)//获得焦点处理事件
204 | {
205 | if(text() == "请输入你的账号" || text() == "请输入密保答案" || text() == "请输入新的密码" || text() == "请确认密码"){
206 | setText("");
207 | }
208 | setStyleSheet("font: 13pt 'Microsoft YaHei UI'; "
209 | "border: 1px solid rgba(0, 0, 0, 0.3); "
210 | "border-radius: 10px; "
211 | "color: black;");
212 | QLineEdit::focusInEvent(event);
213 | }
214 |
215 |
216 | void LineFind::focusOutEvent(QFocusEvent *event)//失去焦点处理事件
217 | {
218 | if(text() == ""){
219 | if(objectName() == "line_pages1"){
220 | setStyleSheet(
221 | "font: 13pt 'Microsoft YaHei UI'; "
222 | "border: 1px solid rgba(0, 0, 0, 0.3); "
223 | "border-radius: 8px; "
224 | "color: grey;"
225 | );
226 | setText("请输入你的账号");
227 | }
228 | else if(objectName() == "line_pages2"){
229 | setStyleSheet(
230 | "font: 13pt 'Microsoft YaHei UI'; "
231 | "border: 1px solid rgba(0, 0, 0, 0.3); "
232 | "border-radius: 8px; "
233 | "color: grey;"
234 | );
235 | setText("请输入密保答案");
236 | }
237 | else if(objectName() == "line_pages3_2"){
238 | setStyleSheet(
239 | "font: 13pt 'Microsoft YaHei UI'; "
240 | "border: 1px solid rgba(0, 0, 0, 0.3); "
241 | "border-radius: 8px; "
242 | "color: grey;"
243 | );
244 | setText("请输入新的密码");
245 | }
246 | else if(objectName() == "line_pages3"){
247 | setStyleSheet(
248 | "font: 13pt 'Microsoft YaHei UI'; "
249 | "border: 1px solid rgba(0, 0, 0, 0.3); "
250 | "border-radius: 8px; "
251 | "color: grey;"
252 | );
253 | setText("请确认密码");
254 | }
255 | }
256 | QLineEdit::focusOutEvent(event);
257 | }
258 |
--------------------------------------------------------------------------------
/user/user/findpassword.h:
--------------------------------------------------------------------------------
1 | #ifndef FINDPASSWORD_H
2 | #define FINDPASSWORD_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | namespace Ui {
19 | class FindPassword;
20 | }
21 |
22 |
23 | class FindPassword : public QMainWindow
24 | {
25 | Q_OBJECT
26 |
27 | public:
28 | explicit FindPassword(QTcpSocket* msocket,QWidget *parent = nullptr);
29 | ~FindPassword();
30 | void setVal();//给输入框设置验证器
31 | void paintEvent(QPaintEvent *event);//初始化背景
32 | void closeEvent(QCloseEvent *event);//关闭窗口事件
33 | void mousePressEvent(QMouseEvent *event);//点击窗口空白让所有输入框失去焦点
34 |
35 | private slots:
36 | void on_but_pages1_clicked();//切换页面
37 | void on_but_pages2_clicked();//切换页面
38 | void on_but_pages3_clicked();//提交最后的修改密码请求
39 |
40 | public slots:
41 | void findPassword1(const QJsonObject &jsonObj);//看看有没有这个账号 对应切换页面或弹窗
42 | void findPassword2(const QJsonObject &jsonObj);//看看问题回答对了没有 对应切换页面或弹窗
43 | void findPassword3(const QJsonObject &jsonObj);//看看修改密码的结果 对应弹窗
44 |
45 | private:
46 | Ui::FindPassword *ui;
47 | QTcpSocket *socket;
48 | QJsonObject jsonObj;
49 | QJsonDocument jsonDoc;
50 | QByteArray jsonData;
51 | QRegularExpressionValidator *validator;
52 | };
53 |
54 |
55 | class LineFind :public QLineEdit//输入文本框
56 | {
57 | Q_OBJECT
58 |
59 | public:
60 | LineFind(QWidget *parent = nullptr) : QLineEdit(parent) {}
61 |
62 | public slots:
63 | void focusInEvent(QFocusEvent *event);//获得焦点处理事件
64 | void focusOutEvent(QFocusEvent *event);//失去焦点处理事件
65 | };
66 |
67 | #endif // FINDPASSWORD_H
68 |
--------------------------------------------------------------------------------
/user/user/friendmessage.cpp:
--------------------------------------------------------------------------------
1 | #include "friendmessage.h"
2 | #include "ui_friendmessage.h"
3 |
4 | FriendMessage::FriendMessage(FriendInfo info, QWidget *parent)
5 | :QDialog(parent), ui(new Ui::FriendMessage)
6 | , friendInfo(info)
7 | {
8 | ui->setupUi(this);
9 | //初始化窗口
10 | QIcon icon(":/pictures/suliao.png");
11 | setWindowIcon(icon);
12 | setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
13 | setAttribute(Qt::WA_TranslucentBackground);
14 | //设置当前页面各信息
15 | setMessage(friendInfo);
16 | // 将窗口居中显示
17 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
18 | if (topLevelParent) {
19 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
20 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
21 | move(x, y);
22 | }
23 | }
24 |
25 |
26 | FriendMessage::~FriendMessage()
27 | {
28 | delete ui;
29 | this->disconnect();
30 | qDebug()<<"好友信息被析构";
31 | }
32 |
33 |
34 | void FriendMessage::paintEvent(QPaintEvent *event)//窗口背景
35 | {
36 | //调用基类方法以处理父类的绘图
37 | QDialog::paintEvent(event);
38 | QPainter painter(this);
39 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
40 | //加载背景图片
41 | QPixmap background(":/pictures/094 Cloudy Apple - trans.png");
42 | //确保图片已加载
43 | if (background.isNull()) {
44 | qWarning("背景图像加载失败");
45 | return;
46 | }
47 | QSize newSize = QSize(this->width(), this->height());
48 | //将背景图缩放为新的大小
49 | QPixmap scaledBackground = background.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
50 | //计算绘制的位置,保持居中
51 | int x = (this->width() - scaledBackground.width()) / 2;
52 | int y = (this->height() - scaledBackground.height()) / 2;
53 | //设置剪裁区域以适应圆角窗口
54 | int radius = 10;
55 | QPainterPath path;
56 | path.addRoundedRect(rect(), radius, radius);
57 | painter.setClipPath(path);
58 | //绘制背景图片
59 | painter.drawPixmap(x, y, scaledBackground);
60 | //绘制边框
61 | painter.setPen(QPen(Qt::gray, 3.5));
62 | painter.drawRoundedRect(rect(), radius, radius);
63 | }
64 |
65 |
66 | void FriendMessage::mousePressEvent(QMouseEvent *event)//捕获鼠标按下事件
67 | {
68 | //清除焦点
69 | QList widgets = this->findChildren();
70 | for (QWidget* widget : widgets) {
71 | widget->clearFocus();
72 | }
73 | QPoint pos = event->pos();
74 | int margin = 30;
75 | if (pos.x() <= 30 || pos.x() >= width() - 30 ||
76 | pos.y() <= 30 || pos.y() >= height() - 30){//如果点击在边缘
77 | qDebug() << "点击在边缘";
78 | moveFlag = 1;
79 | dragPosition = event->globalPosition().toPoint() - this->frameGeometry().topLeft();//记录鼠标相对于窗口的初始偏移
80 | event->accept();
81 | }
82 | }
83 |
84 |
85 | void FriendMessage::mouseMoveEvent(QMouseEvent *event)//实现拖拽移动效果与调整大小效果
86 | {
87 | qDebug()<<"鼠标位移了";
88 | QPoint globalPos = event->globalPosition().toPoint();//获取当前的鼠标位置
89 | QPoint delta = globalPos - (this->frameGeometry().topLeft() + dragPosition);//计算当前鼠标位置与窗口之间的相对偏移
90 | if (event->buttons() & Qt::LeftButton) {
91 | if (moveFlag == 1) {
92 | this->move(globalPos - dragPosition);
93 | event->accept();
94 | }
95 | //更新拖动位置
96 | dragPosition = globalPos - this->frameGeometry().topLeft();
97 | }
98 | }
99 |
100 |
101 | void FriendMessage::mouseReleaseEvent(QMouseEvent *event)//重置移动状态
102 | {
103 | moveFlag = 0;
104 | }
105 |
106 |
107 | QString FriendMessage::pixmapToBase64(const QPixmap &pixmap)//图片转换成base64格式
108 | {
109 | QImage image = pixmap.toImage();
110 | QBuffer buffer;
111 | buffer.open(QIODevice::WriteOnly);
112 | image.save(&buffer, "PNG");
113 | QByteArray byteArray = buffer.data();
114 | return QString(byteArray.toBase64());
115 | }
116 |
117 |
118 | QPixmap FriendMessage::base64ToPixmap(const QString &base64Str)//将base64转换为图片
119 | {
120 | QByteArray byteArray = QByteArray::fromBase64(base64Str.toUtf8());
121 | QImage image;
122 | //尝试加载PNG格式
123 | if (!image.loadFromData(byteArray, "PNG")) {
124 | //如果PNG加载失败,尝试JPG格式
125 | image.loadFromData(byteArray, "JPG");
126 | }
127 | return QPixmap::fromImage(image);
128 | }
129 |
130 |
131 | void FriendMessage::setMessage(const FriendInfo &info)//设置当前页面各信息
132 | {
133 | ui->textEdit_account->setText(info.account);
134 | ui->textEdit_nickname->setText(info.name);
135 | ui->textEdit_sig->setText(info.signature);
136 | ui->textEdit_gender->setText(info.gender);
137 | QPixmap avator = base64ToPixmap(info.avator_base64);
138 | ui->lab_avator->setScaledContents(true);
139 | ui->lab_avator->setPixmap(avator);
140 | }
141 |
142 |
143 | void FriendMessage::on_but_cancelwindow_clicked()//关闭窗口
144 | {
145 | this->close();
146 | this->deleteLater();
147 | }
148 |
149 |
--------------------------------------------------------------------------------
/user/user/friendmessage.h:
--------------------------------------------------------------------------------
1 | #ifndef FRIENDMESSAGE_H
2 | #define FRIENDMESSAGE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | namespace Ui {
17 | class FriendMessage;
18 | }
19 |
20 | class FriendMessage : public QDialog
21 | {
22 | Q_OBJECT
23 |
24 | public:
25 | struct FriendInfo {//存储好友信息
26 | QString account;
27 | QString name;
28 | QString avator_base64;
29 | QString gender;
30 | QString signature;
31 | };
32 |
33 | public:
34 | explicit FriendMessage(FriendInfo info, QWidget *parent = nullptr);
35 | ~FriendMessage();
36 | void paintEvent(QPaintEvent *event);//窗口背景
37 | void mousePressEvent(QMouseEvent *event);//捕获鼠标按下事件
38 | void mouseMoveEvent(QMouseEvent *event);//实现拖拽移动效果与调整大小效果
39 | void mouseReleaseEvent(QMouseEvent *event);//重置移动状态
40 | QString pixmapToBase64(const QPixmap &pixmap);//图片转换成base64格式
41 | QPixmap base64ToPixmap(const QString &base64Str);//将base64转换为图片
42 | void setMessage(const FriendInfo &info);//设置当前页面各信息
43 |
44 | private slots:
45 | void on_but_cancelwindow_clicked();//关闭窗口
46 |
47 | private:
48 | Ui::FriendMessage *ui;
49 | FriendInfo friendInfo;//存储好友信息
50 | int moveFlag = 0;
51 | QPoint dragPosition;
52 | };
53 |
54 | #endif // FRIENDMESSAGE_H
55 |
--------------------------------------------------------------------------------
/user/user/login.h:
--------------------------------------------------------------------------------
1 | #ifndef LOGIN_H
2 | #define LOGIN_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include "registerwindow.h"
30 | #include "findpassword.h"
31 | #include "mainwindow.h"
32 | #include "dialog.h"
33 |
34 | QT_BEGIN_NAMESPACE
35 | namespace Ui {
36 | class Login;
37 | }
38 | QT_END_NAMESPACE
39 |
40 |
41 | class Login : public QMainWindow
42 | {
43 | Q_OBJECT
44 |
45 | public:
46 | Login(QWidget *parent = nullptr);
47 | ~Login();
48 | void setAva();//初始化头像
49 | void setIcon();//初始化左上角图标
50 | void setVal();//设置输入验证器
51 | void setTimer();//设置一些计时器 用于动态背景与动态按钮
52 | bool tcpConnect();//连接服务器
53 | void remeberPassword();//记住密码
54 | void rememberAvator();//记住头像
55 | void ifAutoLogin();//检查自动登录设置
56 | void ifRememberPassword();//如果没有自动登录的检查是否有人记住密码
57 | void paintEvent(QPaintEvent *event);//绘制渐变背景
58 | void mouseMoveEvent(QMouseEvent *event);//拖拽移动窗口位置
59 | void mouseReleaseEvent(QMouseEvent *event);//重置移动状态
60 | void saveAvator(QString avator);//保存头像
61 | void dengLuChengGong();//登录失败
62 | void dengLuShiBai();//登录失败
63 | QPixmap createCircularPixmap(const QString &imagePath);//设置一个调整好掩码的圆形头像
64 | QPixmap getRoundedPixmap(const QPixmap srcPixmap, const int radius);//获得圆角图片
65 | void closeEvent(QCloseEvent *event);//关闭窗口事件
66 |
67 | signals:
68 | void sendAvator();//通知子窗口发送头像给服务器
69 | void zhuCeShiBai();//通知子窗口注册失败
70 | void zhuCeChengGong(QString qqnum);//通知子窗口注册成功
71 | void findPass1(const QJsonObject &jsonObj);//通知子窗口找回密码
72 | void findPass2(const QJsonObject &jsonObj);//通知子窗口回答问题的结果
73 | void findPass3(const QJsonObject &jsonObj);//通知子窗口找回密码的结果
74 | void loginSucceed(const QString account);//登录成功通知main新建一个主窗口
75 |
76 | private slots:
77 | void onReadyRead();//读取服务器发送的消息
78 | void on_gologin_clicked();//点击登录发送请求
79 | void sendLogin();//发送登录信息
80 | void updateLoginText();//更新取消按钮的文本 模拟动态效果
81 | void on_line_password_returnPressed();//回车登录也会发送请求
82 | void on_line_qqnum_returnPressed();//回车登录也会发送请求
83 | void mousePressEvent(QMouseEvent *event);//点击窗口空白让输入框失去焦点 并且判断拖拽窗口
84 | void on_line_password_textChanged(const QString &arg1);//改变密码文本是否判断登录是否可点击
85 | void on_line_qqnum_textChanged(const QString &arg1);//改变登录文本是否判断登录是否可点击
86 | void on_auto_ckbox_toggled(bool checked);//勾选自动登录自动勾选记住密码
87 | void on_ckbox_remeber_toggled(bool checked);//记住密码取消勾选时 如果自动登录仍勾选 则取消
88 | void setSty();//初始设置输入框格式
89 | void on_rgs_pbt_clicked();//注册账号
90 | void on_fgt_pbt_clicked();//找回密码
91 | void updateGradient() ;//更新渐变背景
92 | void on_but_deletewindow_clicked();//关闭按钮
93 |
94 | private:
95 | Ui::Login *ui;
96 | QTcpSocket socket;
97 | QJsonObject jsonObj;
98 | QJsonDocument jsonDoc;
99 | QByteArray jsonData;
100 | QRegularExpressionValidator *validator;
101 | QSettings settings = QSettings("settings.ini", QSettings::IniFormat);
102 | /*存储
103 | / lastlogin: 上次成功登录的用户名。如果有说明则有人记住密码了 没有则说明没人记住密码 不必理会
104 | / 账号/password: 与特定用户相关联的密码。分组存储 组名是账号
105 | */
106 | QSettings set = QSettings("set.ini", QSettings::IniFormat);
107 | /*存储
108 | / autologin: 是否启用自动登录的布尔值。
109 | / autologinuser: 自动登录的用户名。加载后去setting中找密码
110 | */
111 | RegisterWindow* regis;//注册账号窗口对象
112 | FindPassword* finddPassword;//找回密码窗口对象
113 | QTimer *timer;
114 | QPoint dragPosition;
115 | QString saveLoginAvatorPath;//保存上次登录成功的人的头像 用来初始化界面
116 | MainWindow *mainwind;
117 | QTimer *cancelTimer;
118 | bool cancelRequested;
119 | QTimer *textUpdateTimer;//用于更新按钮文本的计时器
120 | int dotCount = 0;//用于更新文本的点计数
121 | bool loginFlag = false;//是不是正在登录
122 | int moveFlag = 0;//用于判断是否要拖动窗口
123 | int offset = 0 ;//渐变尺度;
124 | };
125 |
126 | class LineInput :public QLineEdit//输入框类
127 | {
128 | Q_OBJECT
129 |
130 | public:
131 | LineInput(QWidget *parent = nullptr) : QLineEdit(parent) {}
132 |
133 | public slots:
134 | void focusInEvent(QFocusEvent *event);//获得焦点处理事件
135 | void focusOutEvent(QFocusEvent *event);//失去焦点处理事件
136 | };
137 |
138 | #endif // LOGIN_H
139 |
--------------------------------------------------------------------------------
/user/user/logout.cpp:
--------------------------------------------------------------------------------
1 | #include "logout.h"
2 | #include "ui_logout.h"
3 | #include "dialog.h"
4 | #include "choicedialog.h"
5 |
6 | Logout::Logout(QWidget *parent)
7 | : QDialog(parent)
8 | , ui(new Ui::Logout)
9 | {
10 | ui->setupUi(this);
11 | //初始化窗口
12 | QIcon icon(":/pictures/suliao.png");
13 | setWindowIcon(icon);
14 | setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
15 | setAttribute(Qt::WA_TranslucentBackground);
16 | // 将窗口居中显示
17 | QWidget *topLevelParent = parent ? parent->window() : nullptr;
18 | if (topLevelParent) {
19 | int x = topLevelParent->x() + (topLevelParent->width() - width()) / 2;
20 | int y = topLevelParent->y() + (topLevelParent->height() - height()) / 2;
21 | move(x, y);
22 | }
23 | }
24 |
25 |
26 | Logout::~Logout()
27 | {
28 | delete ui;
29 | }
30 |
31 |
32 | void Logout::on_but_deletewindow_clicked()//关闭窗口
33 | {
34 | this->close();
35 | }
36 |
37 |
38 | void Logout::setVal()//设置输入验证器
39 | {
40 | QRegularExpression regExp("^[a-zA-Z0-9]{1,12}$");//给输入框设置验证器
41 | validator = new QRegularExpressionValidator(regExp, this);
42 | ui->line_account->setValidator(validator);
43 | ui->line_password->setValidator(validator);
44 | }
45 |
46 |
47 | void Logout::paintEvent(QPaintEvent *event)//窗口背景
48 | {
49 | //调用基类方法以处理父类的绘图
50 | QDialog::paintEvent(event);
51 | QPainter painter(this);
52 | painter.setRenderHint(QPainter::Antialiasing);//反锯齿
53 | //加载背景图片
54 | QPixmap background(":/pictures/094 Cloudy Apple - trans.png");
55 | //确保图片已加载
56 | if (background.isNull()) {
57 | qWarning("背景图像加载失败");
58 | return;
59 | }
60 | QSize newSize = QSize(this->width(), this->height());
61 | //将背景图缩放为新的大小
62 | QPixmap scaledBackground = background.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
63 | //计算绘制的位置,保持居中
64 | int x = (this->width() - scaledBackground.width()) / 2;
65 | int y = (this->height() - scaledBackground.height()) / 2;
66 | //设置剪裁区域以适应圆角窗口
67 | int radius = 10;
68 | QPainterPath path;
69 | path.addRoundedRect(rect(), radius, radius);
70 | painter.setClipPath(path);
71 | //绘制背景图片
72 | painter.drawPixmap(x, y, scaledBackground);
73 | //绘制边框
74 | painter.setPen(QPen(Qt::gray, 3.5));
75 | painter.drawRoundedRect(rect(), radius, radius);
76 | }
77 |
78 |
79 | void Logout::mousePressEvent(QMouseEvent *event)//捕获鼠标按下事件
80 | {
81 | //清除焦点
82 | QList widgets = this->findChildren();
83 | for (QWidget* widget : widgets) {
84 | widget->clearFocus();
85 | }
86 | QPoint pos = event->pos();
87 | int margin = 30;
88 | if (pos.x() <= 30 || pos.x() >= width() - 30 ||
89 | pos.y() <= 30 || pos.y() >= height() - 30){//如果点击在边缘
90 | qDebug() << "点击在边缘";
91 | moveFlag = 1;
92 | dragPosition = event->globalPosition().toPoint() - this->frameGeometry().topLeft();//记录鼠标相对于窗口的初始偏移
93 | event->accept();
94 | }
95 | }
96 |
97 |
98 | void Logout::mouseMoveEvent(QMouseEvent *event)//实现拖拽移动效果与调整大小效果
99 | {
100 | qDebug()<<"鼠标位移了";
101 | QPoint globalPos = event->globalPosition().toPoint();//获取当前的鼠标位置
102 | QPoint delta = globalPos - (this->frameGeometry().topLeft() + dragPosition);//计算当前鼠标位置与窗口之间的相对偏移
103 | if (event->buttons() & Qt::LeftButton) {
104 | if (moveFlag == 1) {
105 | this->move(globalPos - dragPosition);
106 | event->accept();
107 | }
108 | //更新拖动位置
109 | dragPosition = globalPos - this->frameGeometry().topLeft();
110 | }
111 | }
112 |
113 |
114 | void Logout::mouseReleaseEvent(QMouseEvent *event)//重置移动状态
115 | {
116 | moveFlag = 0;
117 | }
118 |
119 |
120 | void Logout:: closeEvent(QCloseEvent *event)//关闭窗口事件
121 | {
122 | emit customClose();//this->disconnect();放在主窗口了
123 | this->deleteLater();
124 | event->accept();
125 | }
126 |
127 |
128 | void Logout::on_line_account_textChanged(const QString &arg1)//判断确认是否可以点击
129 | {
130 | if(ui->line_account->text() != "" && ui->line_account->text() != "请输入您的账号"
131 | && ui->line_password->text() != "" && ui->line_password->text() != "请输入您的密码"){
132 | ui->but_yes->setEnabled(true);
133 | ui->but_yes->setStyleSheet(
134 | "QPushButton {"
135 | "font: 12pt 'Microsoft YaHei UI';"
136 | "background-color: rgb(5, 186, 251);"
137 | "color: white;"
138 | "border-radius: 10px;"
139 | "border: 0.5px solid rgb(220, 220, 220);"
140 | "}"
141 | "QPushButton:hover {"
142 | "background-color: rgba(5, 186, 251, 0.7);"
143 | "color: white;"
144 | "border-radius: 10px;"
145 | "}"
146 | "QPushButton:pressed {"
147 | "background-color: rgba(0, 123, 255, 0.8);"
148 | "color: rgba(255, 255, 255, 0.9);"
149 | "border-radius: 10px;"
150 | "}"
151 | );
152 | }
153 | else{
154 | ui->but_yes->setEnabled(false);
155 | ui->but_yes->setStyleSheet(
156 | "QPushButton {"
157 | "font: 12pt 'Microsoft YaHei UI';"
158 | "background-color: rgb(167, 214, 255); "
159 | "color: white;"
160 | "border-radius: 10px;"
161 | "}"
162 | );
163 | }
164 | }
165 |
166 |
167 | void Logout::on_line_password_textChanged(const QString &arg1)//判断确认是否可以点击
168 | {
169 | if(ui->line_account->text() != "" && ui->line_account->text() != "请输入您的账号"
170 | && ui->line_password->text() != "" && ui->line_password->text() != "请输入您的密码"){
171 | ui->but_yes->setEnabled(true);
172 | ui->but_yes->setStyleSheet(
173 | "QPushButton {"
174 | "font: 12pt 'Microsoft YaHei UI';"
175 | "background-color: rgb(5, 186, 251);"
176 | "color: white;"
177 | "border-radius: 10px;"
178 | "border: 0.5px solid rgb(220, 220, 220);"
179 | "}"
180 | "QPushButton:hover {"
181 | "background-color: rgba(5, 186, 251, 0.7);"
182 | "color: white;"
183 | "border-radius: 10px;"
184 | "}"
185 | "QPushButton:pressed {"
186 | "background-color: rgba(0, 123, 255, 0.8);"
187 | "color: rgba(255, 255, 255, 0.9);"
188 | "border-radius: 10px;"
189 | "}"
190 | );
191 | }
192 | else{
193 | ui->but_yes->setEnabled(false);
194 | ui->but_yes->setStyleSheet(
195 | "QPushButton {"
196 | "font: 12pt 'Microsoft YaHei UI';"
197 | "background-color: rgb(167, 214, 255); "
198 | "color: white;"
199 | "border-radius: 10px;"
200 | "}"
201 | );
202 | }
203 | }
204 |
205 |
206 | void Logout::on_but_yes_clicked()//是否确定注销
207 | {
208 | ChoiceDialog dialog;
209 | dialog.transText("你确定永久注销此账号吗?");
210 | dialog.transButText("取消", "确定");
211 | int result = dialog.exec();
212 | if(result == QDialog::Rejected){
213 | close();
214 | }
215 | else if(result == QDialog::Accepted){
216 | QJsonObject json;
217 | json["tag"] = "logout";
218 | json["account"] = ui->line_account->text();
219 | json["password"] = ui->line_password->text();
220 | emit logout(json);
221 | }
222 | }
223 |
224 |
225 | void Logout::logoutAnswer(const QJsonObject& json)//注销的结果
226 | {
227 | if(json["answer"] == "user_not_found"){
228 | Dialog dialog;
229 | dialog.transText("账号或密码错误,请检查!");
230 | dialog.exec();
231 | }
232 | else if(json["answer"] == "fail"){
233 | Dialog dialog;
234 | dialog.transText("注销失败!");
235 | dialog.exec();
236 | }
237 | }
238 |
239 |
240 | void LineLogout::focusInEvent(QFocusEvent *event)//获得焦点处理事件
241 | {
242 | if(text() == "请输入您的账号" || text() == "请输入您的密码"){
243 | setText("");
244 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
245 | "border: 1px solid rgba(0, 0, 0, 0.1);"
246 | "border-radius: 8px;"
247 | "padding: 5px;"
248 | "color: black;");
249 | }
250 | if(objectName() == "line_password"){
251 | this->setEchoMode(Password);
252 | }
253 | QLineEdit::focusInEvent(event);
254 | }
255 |
256 |
257 | void LineLogout::focusOutEvent(QFocusEvent *event)//失去焦点处理事件
258 | {
259 | if(text() == ""){
260 | if(objectName() == "line_accont")
261 | {
262 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
263 | "border: 1px solid rgba(0, 0, 0, 0.1);"
264 | "border-radius: 8px;"
265 | "padding: 5px;"
266 | "color: grey;");
267 | setText("请输入您的账号");
268 | }
269 | if(objectName() == "line_password")
270 | {
271 | setStyleSheet("font: 12pt 'Microsoft YaHei UI';"
272 | "border: 1px solid rgba(0, 0, 0, 0.1);"
273 | "border-radius: 8px;"
274 | "padding: 5px;"
275 | "color: grey;");
276 | setText("请输入您的密码");
277 | setEchoMode(Normal);
278 | }
279 | }
280 | QLineEdit::focusOutEvent(event);
281 | }
282 |
283 |
284 |
--------------------------------------------------------------------------------
/user/user/logout.h:
--------------------------------------------------------------------------------
1 | #ifndef LOGOUT_H
2 | #define LOGOUT_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | namespace Ui {
14 | class Logout;
15 | }
16 |
17 | class Logout : public QDialog//注销类
18 | {
19 | Q_OBJECT
20 |
21 | public:
22 | explicit Logout(QWidget *parent = nullptr);
23 | ~Logout();
24 | void setVal();//设置输入验证器
25 | void paintEvent(QPaintEvent *event);//窗口背景
26 | void mousePressEvent(QMouseEvent *event);//捕获鼠标按下事件
27 | void mouseMoveEvent(QMouseEvent *event);//实现拖拽移动效果与调整大小效果
28 | void mouseReleaseEvent(QMouseEvent *event);//重置移动状态
29 | void closeEvent(QCloseEvent *event);//关闭窗口事件
30 |
31 | private slots:
32 | void on_but_deletewindow_clicked();//关闭窗口
33 | void on_line_account_textChanged(const QString &arg1);//判断确认是否可以点击
34 | void on_line_password_textChanged(const QString &arg1);//判断确认是否可以点击
35 | void on_but_yes_clicked();//是否确定注销
36 |
37 | public slots:
38 | void logoutAnswer(const QJsonObject& json);//注销的结果
39 |
40 | signals:
41 | void customClose();//发出退出的信号
42 | void logout(const QJsonObject &json);//告知主窗体发送注销申请
43 |
44 | private:
45 | Ui::Logout *ui;
46 | int moveFlag = 0;
47 | QPoint dragPosition;
48 | QValidator *validator;
49 | };
50 |
51 |
52 | class LineLogout:public QLineEdit//输入框类
53 | {
54 | Q_OBJECT
55 |
56 | public:
57 | LineLogout(QWidget *parent = nullptr) : QLineEdit(parent) {}
58 |
59 | public slots:
60 | void focusInEvent(QFocusEvent *event);//获得焦点处理事件
61 | void focusOutEvent(QFocusEvent *event);//失去焦点处理事件
62 | };
63 |
64 | #endif // LOGOUT_H
65 |
--------------------------------------------------------------------------------
/user/user/logout.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Logout
4 |
5 |
6 |
7 | 0
8 | 0
9 | 302
10 | 187
11 |
12 |
13 |
14 | Dialog
15 |
16 |
17 | border:none;
18 |
19 |
20 | -
21 |
22 |
-
23 |
24 |
25 |
26 | 0
27 | 0
28 |
29 |
30 |
31 | font: 700 11pt "Microsoft YaHei UI";
32 | border:none;
33 |
34 |
35 | 注销账号
36 |
37 |
38 | Qt::AlignmentFlag::AlignCenter
39 |
40 |
41 |
42 | -
43 |
44 |
45 |
46 | 0
47 | 15
48 |
49 |
50 |
51 |
52 | 20
53 | 20
54 |
55 |
56 |
57 |
58 | 20
59 | 20
60 |
61 |
62 |
63 | QPushButton {
64 | border: none;
65 | background: transparent;
66 | color: rgb(78, 78, 78);
67 | font: 16pt 'Microsoft New Tai Lue';
68 | }
69 |
70 | QPushButton:hover {
71 | border: none;
72 | background: transparent;
73 | color: white;
74 | font: 16pt 'Microsoft New Tai Lue';
75 | background: red;
76 | border-radius: 3px;
77 | }
78 |
79 |
80 | x
81 |
82 |
83 | false
84 |
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
-
92 |
93 |
94 |
95 | 0
96 | 0
97 |
98 |
99 |
100 |
101 | 0
102 | 50
103 |
104 |
105 |
106 | font: 12pt "Microsoft YaHei UI";
107 | border:none;
108 | color:black;
109 |
110 |
111 |
112 | 输入账号:
113 |
114 |
115 |
116 | -
117 |
118 |
119 |
120 | 0
121 | 0
122 |
123 |
124 |
125 |
126 | 224
127 | 38
128 |
129 |
130 |
131 |
132 | 224
133 | 38
134 |
135 |
136 |
137 | Qt::FocusPolicy::ClickFocus
138 |
139 |
140 | Qt::ContextMenuPolicy::NoContextMenu
141 |
142 |
143 | font: 12pt "Microsoft YaHei UI";
144 | border: 1px solid rgba(0, 0, 0, 0.1);
145 | border-radius: 8px;
146 | padding:5px;
147 | color:grey;
148 |
149 |
150 |
151 |
152 | 请输入您的账号
153 |
154 |
155 | 12
156 |
157 |
158 |
159 |
160 |
161 | -
162 |
163 |
-
164 |
165 |
166 |
167 | 0
168 | 0
169 |
170 |
171 |
172 |
173 | 0
174 | 50
175 |
176 |
177 |
178 | font: 12pt "Microsoft YaHei UI";
179 | border:none;
180 | color:black;
181 |
182 |
183 |
184 | 输入密码:
185 |
186 |
187 |
188 | -
189 |
190 |
191 |
192 | 0
193 | 0
194 |
195 |
196 |
197 |
198 | 224
199 | 38
200 |
201 |
202 |
203 |
204 | 224
205 | 38
206 |
207 |
208 |
209 | Qt::FocusPolicy::ClickFocus
210 |
211 |
212 | Qt::ContextMenuPolicy::NoContextMenu
213 |
214 |
215 | font: 12pt "Microsoft YaHei UI";
216 | border: 1px solid rgba(0, 0, 0, 0.1);
217 | border-radius: 8px;
218 | padding:5px;
219 | color:grey;
220 |
221 |
222 |
223 |
224 | 请输入您的密码
225 |
226 |
227 | 12
228 |
229 |
230 |
231 |
232 |
233 | -
234 |
235 |
-
236 |
237 |
238 | Qt::Orientation::Horizontal
239 |
240 |
241 |
242 | 40
243 | 20
244 |
245 |
246 |
247 |
248 | -
249 |
250 |
251 | false
252 |
253 |
254 |
255 | 0
256 | 0
257 |
258 |
259 |
260 |
261 | 175
262 | 35
263 |
264 |
265 |
266 | PointingHandCursor
267 |
268 |
269 | QPushButton {
270 | font: 12pt "Microsoft YaHei UI";
271 | background-color: rgb(167, 214, 255);
272 | color: white;
273 | border-radius: 10px;
274 | }
275 |
276 |
277 |
278 | 确认
279 |
280 |
281 |
282 | -
283 |
284 |
285 | Qt::Orientation::Horizontal
286 |
287 |
288 |
289 | 40
290 | 20
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 | LineChangePass
302 | QLineEdit
303 |
304 |
305 |
306 |
307 |
308 |
309 |
--------------------------------------------------------------------------------
/user/user/main.cpp:
--------------------------------------------------------------------------------
1 | #include "login.h"
2 | #include "mainwindow.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | QApplication a(argc, argv);
12 | QTranslator translator;
13 | const QStringList uiLanguages = QLocale::system().uiLanguages();
14 | for (const QString &locale : uiLanguages) {
15 | const QString baseName = "user_" + QLocale(locale).name();
16 | if (translator.load(":/i18n/" + baseName)) {
17 | a.installTranslator(&translator);
18 | break;
19 | }
20 | }
21 | Login w;
22 | //使用std::unique_ptr管理 QTcpSocket的实例
23 | auto socket = std::make_unique();
24 | //使用QPointer来管理 MainWindow的指针
25 | QPointer mainWind = nullptr;
26 | //连接login窗口的 loginsucceed信号到槽
27 | QObject::connect(&w, &Login::loginSucceed, [&](const QString &account) {
28 | if (!mainWind) {
29 | mainWind = new MainWindow(account);
30 | mainWind->show();
31 | }
32 | });
33 | w.show();
34 | //////////////////////////////////////////////////////////////////
35 | Login w2;
36 | //使用std::unique_ptr管理 QTcpSocket的实例
37 | auto socket2 = std::make_unique();
38 | //使用QPointer来管理 MainWindow的指针
39 | QPointer mainWind2 = nullptr;
40 | //连接login 窗口的 loginsucceed信号到槽
41 | QObject::connect(&w2, &Login::loginSucceed, [&](const QString &account) {
42 | if (!mainWind2) {
43 | mainWind2 = new MainWindow(account);
44 | mainWind2->show();
45 | }
46 | });
47 | w2.show();
48 | return a.exec();
49 | }
50 |
--------------------------------------------------------------------------------
/user/user/mainwindow-else.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW-ELSE_H
2 | #define MAINWINDOW-ELSE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 |
44 |
45 | class TalkFilterProxyModel;
46 |
47 |
48 | class TalkList : public QListView//消息列表类
49 | {
50 | Q_OBJECT
51 |
52 | public:
53 | TalkList(QWidget *parent = nullptr) : QListView(parent) {
54 | }
55 |
56 | protected:
57 | void contextMenuEvent(QContextMenuEvent *event);//菜单
58 |
59 | signals:
60 | void choiceDone(const QJsonObject &json);
61 | };
62 |
63 |
64 | class FriendList : public QListView//好友列表类
65 | {
66 | Q_OBJECT
67 |
68 | public:
69 | FriendList(QWidget *parent = nullptr) : QListView(parent) {
70 | }
71 |
72 | void mousePressEvent(QMouseEvent *event);//实现左右键都可选择
73 | };
74 |
75 |
76 | class FriendDelegate : public QStyledItemDelegate//好友列表委托绘图类
77 | {
78 | Q_OBJECT
79 | public:
80 | FriendDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
81 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;//好友列表项委托绘图
82 | QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;//返回尺寸
83 | QPixmap getRoundedPixmap(QPixmap srcPixmap, const int radius)const;//获得圆角图片
84 | };
85 |
86 |
87 | class TalkDelegate : public QStyledItemDelegate//聊天列表委托绘图类
88 | {
89 | Q_OBJECT
90 | public:
91 | TalkDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
92 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;//聊天列表项委托绘图
93 | QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;//返回尺寸
94 | QPixmap getRoundedPixmap(QPixmap srcPixmap, const int radius)const;//获得圆角图片
95 | QString displayTimeComparison(const QString ×tampStr)const;//解析时间戳
96 | };
97 |
98 |
99 | class FilterProxyModel : public QSortFilterProxyModel//好友列表过滤代理模型
100 | {
101 | Q_OBJECT
102 | public:
103 | explicit FilterProxyModel(QObject *parent = nullptr)
104 | : QSortFilterProxyModel(parent) {
105 | }
106 |
107 | protected:
108 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)const;//好友列表过滤代理模型判断是否接收
109 | };
110 |
111 |
112 | class TalkFilterProxyModel : public QSortFilterProxyModel//聊天列表过滤代理模型
113 | {
114 | Q_OBJECT
115 | public:
116 | explicit TalkFilterProxyModel(QObject *parent = nullptr)
117 | : QSortFilterProxyModel(parent) {
118 | }
119 |
120 | protected:
121 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)const;//聊天列表过滤代理模型判断是否接收
122 | };
123 |
124 |
125 | class LineSerach :public QLineEdit//搜索框类
126 | {
127 | Q_OBJECT
128 |
129 | public:
130 | LineSerach(QWidget *parent = nullptr) : QLineEdit(parent) {}
131 |
132 | public slots:
133 | void focusInEvent(QFocusEvent *event);//获得焦点处理事件
134 | void focusOutEvent(QFocusEvent *event);//失去焦点处理事件
135 |
136 | };
137 |
138 |
139 | class LabelAva:public QLabel//实现点击头像弹出修改信息窗口
140 | {
141 | Q_OBJECT
142 |
143 | public:
144 | LabelAva(QWidget *parent=nullptr):QLabel(parent){}
145 | void mousePressEvent(QMouseEvent *event);//点击头像发出弹出修改个人信息窗口的信号
146 |
147 | signals:
148 | void changeInfo();
149 | };
150 |
151 |
152 | class LabelFriendAva:public QLabel//实现点击头像弹出好友信息窗口(好友申请内的)
153 | {
154 | Q_OBJECT
155 |
156 | public:
157 | LabelFriendAva(QWidget *parent=nullptr):QLabel(parent){}
158 | void mousePressEvent(QMouseEvent *event);//点击头像弹出好友个人信息
159 | };
160 |
161 |
162 | class LabelFriendAvaInMessage:public QLabel//实现点击头像弹出好友信息窗口(消息页面内的)
163 | {
164 | Q_OBJECT
165 |
166 | public:
167 | LabelFriendAvaInMessage(QWidget *parent=nullptr):QLabel(parent){}
168 | void mousePressEvent(QMouseEvent *event);//点击头像弹出好友个人信息
169 |
170 | signals:
171 | void showMessage();
172 | };
173 |
174 |
175 | class CustomTextEdit : public QTextEdit//显示好友信息的edit类
176 | {
177 | public:
178 | CustomTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) , background(":/pictures/andan_touming.jpg"){}
179 | QPixmap background;//背景图
180 |
181 | protected:
182 | void paintEvent(QPaintEvent *event);//右边edit的背景
183 | };
184 |
185 |
186 | class TalkStacked : public QStackedWidget//显示聊天信息的类
187 | {
188 | public:
189 | TalkStacked(QWidget *parent = nullptr): QStackedWidget(parent), background(":/pictures/andan_touming.jpg"){};
190 | QPixmap background;//背景图
191 |
192 | protected:
193 | void paintEvent(QPaintEvent *event);//右边edit的背景
194 |
195 | };
196 |
197 |
198 | class ImageLabel : public QLabel//图片消息框
199 | {
200 | Q_OBJECT
201 |
202 | public:
203 | explicit ImageLabel(const QPixmap &pixmap, QWidget *parent = nullptr);
204 |
205 | protected:
206 | void mousePressEvent(QMouseEvent *event) override;//鼠标按下事件打开图片
207 | void contextMenuEvent(QContextMenuEvent *event) override;//用户右键点击时显示菜单
208 |
209 | private:
210 | QPixmap myPixmap;
211 | };
212 |
213 |
214 | class EnterTextEdit : public QTextEdit {
215 | Q_OBJECT
216 |
217 | public:
218 | EnterTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) {}
219 |
220 | protected:
221 | void keyPressEvent(QKeyEvent *event) override;//按下判断是不是回车加ctrl
222 |
223 | signals:
224 | void enterKey();//回车和ctrl键被按下
225 | };
226 | #endif // MAINWINDOW-ELSE_H
227 |
--------------------------------------------------------------------------------
/user/user/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include