李臻20242817_安全文件传输系统项目报告_第9周

安全文件传输系统项目报告(第 9 周)

1. 代码链接

Gitee 仓库地址:https://gitee.com/li-zhen1215/homework/tree/master/Secure-file

代码结构说明:

plaintext 复制代码
project-root/
 ├── src/ # 源代码目录
 │ ├── main.c # 主程序入口
 │ ├── db/ # 数据库操作
 │ ├── gui/ # 图形界面
 │ └── utils/ # 工具函数模块
 ├── include/ # 头文件
 ├── lib/ # 动态库静态库
 ├── docs/ # 文档目录
 ├── Makefile # 自动编译
 └── README.md # 项目说明

1、使用QT

  1. 建立空白项目

打开QTCreator,选择File->New File or Project

输入项目名称并选择存储路径。

编辑模式下,在工程文件中添加相应模块信息,如:QT += widgets

将书写好的cpp和h文件导入到QT项目中

mainwindow.h

csharp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onButtonClicked();

private:
    QPushButton *button;
};

#endif // MAINWINDOW_H

mainwindow.cpp

csharp 复制代码
#include "mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // 设置窗口大小和标题
    this->resize(400, 300);
    this->setWindowTitle("简单QT示例");

    // 创建按钮
    button = new QPushButton("点击我", this);
    button->setGeometry(150, 100, 100, 50);

    // 连接按钮的点击信号到槽函数
    connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked);
}

MainWindow::~MainWindow()
{
    delete button;
}

void MainWindow::onButtonClicked()
{
    QMessageBox::information(this, "消息", "你好,QT世界!");
}

main.cpp

csharp 复制代码
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

保存后编译运行,选中工程目录点击右键,"运行",即可编译运行程序

运行后:

2、制作登陆界面

mainwindow.h

csharp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onLoginClicked();
    void onRegisterClicked();

private:
    QLabel *titleLabel;
    QLabel *usernameLabel;
    QLabel *passwordLabel;
    QLineEdit *usernameEdit;
    QLineEdit *passwordEdit;
    QPushButton *loginButton;
    QPushButton *registerButton;
};

#endif // MAINWINDOW_H

mainwindow.cpp

csharp 复制代码
#include "mainwindow.h"
#include <QMessageBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // 设置窗口属性
    this->setWindowTitle("系统登录");
    this->resize(400, 300);

    // 创建中央部件和布局
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);

    // 标题
    titleLabel = new QLabel("欢迎登录系统", this);
    titleLabel->setAlignment(Qt::AlignCenter);
    QFont titleFont = titleLabel->font();
    titleFont.setPointSize(20);
    titleLabel->setFont(titleFont);

    // 表单布局
    QFormLayout *formLayout = new QFormLayout();

    // 用户名
    usernameLabel = new QLabel("用户名:", this);
    usernameEdit = new QLineEdit(this);
    usernameEdit->setPlaceholderText("请输入用户名");
    formLayout->addRow(usernameLabel, usernameEdit);

    // 密码
    passwordLabel = new QLabel("密码:", this);
    passwordEdit = new QLineEdit(this);
    passwordEdit->setPlaceholderText("请输入密码");
    passwordEdit->setEchoMode(QLineEdit::Password);
    formLayout->addRow(passwordLabel, passwordEdit);

    // 按钮布局
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    loginButton = new QPushButton("登录", this);
    registerButton = new QPushButton("注册", this);
    buttonLayout->addWidget(loginButton);
    buttonLayout->addWidget(registerButton);

    // 添加到主布局
    mainLayout->addWidget(titleLabel);
    mainLayout->addLayout(formLayout);
    mainLayout->addLayout(buttonLayout);

    // 设置中央部件
    this->setCentralWidget(centralWidget);

    // 连接信号和槽
    connect(loginButton, &QPushButton::clicked, this, &MainWindow::onLoginClicked);
    connect(registerButton, &QPushButton::clicked, this, &MainWindow::onRegisterClicked);
}

MainWindow::~MainWindow()
{
    // 析构函数
}

void MainWindow::onLoginClicked()
{
    QString username = usernameEdit->text();
    QString password = passwordEdit->text();

    if(username.isEmpty() || password.isEmpty()) {
        QMessageBox::warning(this, "警告", "用户名和密码不能为空!");
        return;
    }

    // 这里应该添加实际的登录验证逻辑
    QMessageBox::information(this, "登录成功", "欢迎, " + username + "!");
}

void MainWindow::onRegisterClicked()
{
    QString username = usernameEdit->text();
    QString password = passwordEdit->text();

    if(username.isEmpty() || password.isEmpty()) {
        QMessageBox::warning(this, "警告", "用户名和密码不能为空!");
        return;
    }

    // 这里应该添加实际的注册逻辑
    QMessageBox::information(this, "注册成功", "用户 " + username + " 注册成功!");
}

main.cpp

csharp 复制代码
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

运行效果

3、尝试链接MySQL数据库

在 .pro 文件中添加 SQL 模块:

csharp 复制代码
QT += core gui widgets sql

mainwindow.h

csharp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onLoginClicked();
    void onRegisterClicked();
    bool connectToDatabase();
    bool userExists(const QString &username);
    bool registerUser(const QString &username, const QString &password);
    bool validateUser(const QString &username, const QString &password);

private:
    // 界面控件
    QLabel *titleLabel;
    QLabel *usernameLabel;
    QLabel *passwordLabel;
    QLineEdit *usernameEdit;
    QLineEdit *passwordEdit;
    QPushButton *loginButton;
    QPushButton *registerButton;
    
    // 数据库连接
    QSqlDatabase db;
};

#endif // MAINWINDOW_H

准备数据库

csharp 复制代码
CREATE DATABASE qt_login;
USE qt_login;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(50) NOT NULL
);

mainwindow.cpp

csharp 复制代码
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // 初始化界面
    setWindowTitle("系统登录");
    resize(400, 300);
    
    // 尝试连接数据库
    if(!connectToDatabase()) {
        QMessageBox::critical(this, "错误", "无法连接数据库!");
        return;
    }

    // 创建界面控件
    titleLabel = new QLabel("欢迎登录系统", this);
    titleLabel->setAlignment(Qt::AlignCenter);
    QFont titleFont = titleLabel->font();
    titleFont.setPointSize(20);
    titleLabel->setFont(titleFont);

    usernameLabel = new QLabel("用户名:", this);
    usernameEdit = new QLineEdit(this);
    usernameEdit->setPlaceholderText("请输入用户名");

    passwordLabel = new QLabel("密码:", this);
    passwordEdit = new QLineEdit(this);
    passwordEdit->setPlaceholderText("请输入密码");
    passwordEdit->setEchoMode(QLineEdit::Password);

    loginButton = new QPushButton("登录", this);
    registerButton = new QPushButton("注册", this);

    // 设置布局
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
    QFormLayout *formLayout = new QFormLayout();
    QHBoxLayout *buttonLayout = new QHBoxLayout();

    formLayout->addRow(usernameLabel, usernameEdit);
    formLayout->addRow(passwordLabel, passwordEdit);
    buttonLayout->addWidget(loginButton);
    buttonLayout->addWidget(registerButton);

    mainLayout->addWidget(titleLabel);
    mainLayout->addLayout(formLayout);
    mainLayout->addLayout(buttonLayout);
    setCentralWidget(centralWidget);

    // 连接信号槽
    connect(loginButton, &QPushButton::clicked, this, &MainWindow::onLoginClicked);
    connect(registerButton, &QPushButton::clicked, this, &MainWindow::onRegisterClicked);
}

MainWindow::~MainWindow()
{
    // 关闭数据库连接
    if(db.isOpen()) {
        db.close();
    }
}

bool MainWindow::connectToDatabase()
{
    // 添加 MySQL 驱动
    db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");      // 数据库服务器地址
    db.setDatabaseName("qt_login");   // 数据库名
    db.setUserName("root");           // 数据库用户名
    db.setPassword("123456");       // 数据库密码
    
    if(!db.open()) {
        QMessageBox::critical(this, "数据库错误", db.lastError().text());
        return false;
    }
    
    // 检查表是否存在,不存在则创建
    QSqlQuery query;
    if(!query.exec("CREATE TABLE IF NOT EXISTS users ("
                  "id INT AUTO_INCREMENT PRIMARY KEY,"
                  "username VARCHAR(50) NOT NULL UNIQUE,"
                  "password VARCHAR(50) NOT NULL)")) {
        QMessageBox::critical(this, "数据库错误", query.lastError().text());
        return false;
    }
    
    return true;
}

bool MainWindow::userExists(const QString &username)
{
    QSqlQuery query;
    query.prepare("SELECT username FROM users WHERE username = :username");
    query.bindValue(":username", username);
    
    if(!query.exec()) {
        QMessageBox::critical(this, "数据库错误", query.lastError().text());
        return false;
    }
    
    return query.next(); // 如果找到记录返回true
}

bool MainWindow::registerUser(const QString &username, const QString &password)
{
    QSqlQuery query;
    query.prepare("INSERT INTO users (username, password) VALUES (:username, :password)");
    query.bindValue(":username", username);
    query.bindValue(":password", password); // 实际应用中应该加密
    
    if(!query.exec()) {
        QMessageBox::critical(this, "注册失败", query.lastError().text());
        return false;
    }
    
    return true;
}

bool MainWindow::validateUser(const QString &username, const QString &password)
{
    QSqlQuery query;
    query.prepare("SELECT username FROM users WHERE username = :username AND password = :password");
    query.bindValue(":username", username);
    query.bindValue(":password", password); // 实际应用中应该比较加密后的密码
    
    if(!query.exec()) {
        QMessageBox::critical(this, "数据库错误", query.lastError().text());
        return false;
    }
    
    return query.next(); // 如果找到匹配记录返回true
}

void MainWindow::onLoginClicked()
{
    QString username = usernameEdit->text().trimmed();
    QString password = passwordEdit->text().trimmed();

    if(username.isEmpty() || password.isEmpty()) {
        QMessageBox::warning(this, "警告", "用户名和密码不能为空!");
        return;
    }

    if(validateUser(username, password)) {
        QMessageBox::information(this, "登录成功", "欢迎, " + username + "!");
        // 这里可以跳转到主界面
    } else {
        QMessageBox::warning(this, "登录失败", "用户名或密码错误!");
    }
}

void MainWindow::onRegisterClicked()
{
    QString username = usernameEdit->text().trimmed();
    QString password = passwordEdit->text().trimmed();

    if(username.isEmpty() || password.isEmpty()) {
        QMessageBox::warning(this, "警告", "用户名和密码不能为空!");
        return;
    }

    if(userExists(username)) {
        QMessageBox::warning(this, "注册失败", "用户名已存在!");
        return;
    }

    if(registerUser(username, password)) {
        QMessageBox::information(this, "注册成功", "用户 " + username + " 注册成功!");
    }
}

4. 遇到的问题及解决方式

问题1:Qt项目无法识别路径

  • 现象:在QT程序中,cpp内容无法识别头文件。
  • 原因:将头文件和cpp文件放在了不同的目录下。
  • 解决:将这些文件移动到同一个目录下,重新添加到QT项目并编译即可运行。

问题2:数据库驱动错误

  • 现象:在QT程序中,无法加载MySQL数据库驱动。
  • 原因:QT的MySQL驱动没有正确编译。
  • 解决:通过下述方法即可实现数据库编译。

安装 MySQL 开发库:

csharp 复制代码
sudo apt-get update
sudo apt-get install libmysqlclient-dev

编译本地MySQL目录

csharp 复制代码
sudo apt-get install libmysqlclient-dev
cd /opt/Qt/5.15.2/Src/qtbase/src/plugins/sqldrivers/mysql
qmake
make
sudo make install

5. 提交报告文档要求

Markdown 文档

  • 本报告使用 Markdown 编写,文件名为 姓名学号_项目名称_第 XX 周.md
  • 包含代码块、图片链接、列表等标准语法。

转换为 PDF

  • 工具:使用 VS Code 插件 Markdown PDF 或在线工具 Pandoc。

  • 步骤

    bash 复制代码
    # 命令行转换示例
    pandoc project-report.md -o project-report.pdf --pdf-engine=xelatex
相关推荐
淋一遍下雨天2 分钟前
Spark Streaming核心编程总结(四)
java·开发语言·数据库
zru_960231 分钟前
Windows 安装 MongoDB 教程
数据库·mongodb
数据与后端架构提升之路1 小时前
深度解析如何将图像帧和音频片段特征高效存储到向量数据库 Milvus
数据库·opencv·音视频
小白考证进阶中2 小时前
0基础可以考MySQL OCP么?备考时间需要多久?
数据库·mysql·开闭原则
观无2 小时前
Redis远程链接应用案例
数据库·redis·缓存·c#
星星点点洲2 小时前
【缓存与数据库结合方案】伪从技术 vs 直接同步/MQ方案的深度对比
数据库·缓存
努力奋斗的小杨2 小时前
学习MySQL的第十二天
数据库·笔记·学习·mysql·navicat
智驱力人工智能3 小时前
无感通行与精准管控:AI单元楼安全方案的技术融合实践
人工智能·安全·智慧城市·智慧园区
枫叶20003 小时前
OceanBase数据库-学习笔记1-概论
数据库·笔记·学习·oceanbase