在工业软件和嵌入式系统开发领域,Qt框架凭借其跨平台特性和强大的GUI能力始终占据重要地位。
本文将基于真实企业级项目实践,详细拆解如何使用C++ Qt开发一个功能完备的汽车销售管理系统(CRM)。
我们将聚焦三大核心模块:SQLite数据库设计、安全登录系统以及销售统计与XML报表生成,每个技术点都将结合代码实例深度剖析。适合中级开发者进阶学习。
一、项目架构
1.1 系统功能全景
- 核心模块:销售管理(车辆入库/出库)品牌/厂家信息管理用户权限与密码安全销售数据可视化统计XML报表生成与打印
1.2 技术栈组成
技术方向 | 具体实现 |
Qt框架基础 | QWidget体系、信号槽机制、多窗口管理 |
数据库层 | SQLite嵌入式数据库、QSqlDatabase操作、事务控制 |
数据持久化 | XML数据生成(QDomDocument)、CSV导出 |
安全机制 | MD5密码加密、QPdfWriter防篡改报表 |
界面交互 | QSS样式定制、QChart数据可视化、自定义QDialog |
二、数据库设计与实现
2.1 SQLite表结构设计
-- 用户表
CREATE TABLE User (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR(32) NOT NULL UNIQUE,
password_hash CHAR(32) NOT NULL -- MD5加密存储
);
-- 汽车品牌表
CREATE TABLE Brand (
brand_id INTEGER PRIMARY KEY,
name VARCHAR(64) NOT NULL,
factory_id INTEGER REFERENCES Factory(factory_id)
);
-- 销售记录表
CREATE TABLE SalesRecord (
record_id INTEGER PRIMARY KEY,
car_id INTEGER REFERENCES Car(car_id),
sale_date DATETIME DEFAULT CURRENT_TIMESTAMP,
amount DECIMAL(10,2)
);
2.2 Qt数据库连接封装
// DatabaseManager.h
class DatabaseManager : public QObject {
Q_OBJECT
public:
static DatabaseManager& instance();
bool initialize(const QString& path);
QSqlQuery executeQuery(const QString& query);
private:
explicit DatabaseManager(QObject *parent = nullptr);
QSqlDatabase m_db;
};
// 初始化示例
bool DatabaseManager::initialize(const QString &path) {
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(path);
if (!m_db.open()) {
qCritical() << "Database connection error:" << m_db.lastError();
return false;
}
// 启用外键约束
executeQuery("PRAGMA foreign_keys = ON;");
return true;
}
三、登录模块实现(安全与用户体验)
3.1 登录界面设计
3.2 密码安全处理
// AuthManager.cpp
#include
QString encryptPassword(const QString& plain) {
QByteArray data = plain.toUtf8();
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
}
bool validateUser(const QString& user, const QString& pass) {
QString hashed = encryptPassword(pass);
QSqlQuery query;
query.prepare("SELECT 1 FROM user_table WHERE username=? AND password=?");
query.addBindValue(user);
query.addBindValue(hashed);
return query.exec() && query.next(); // 查询成功且有结果
}
安全策略:
- SHA-256哈希加密存储密码
- 预处理语句防止SQL注入
- 会话令牌管理(可选JWT)
四、销售统计与XML报表
4.1 数据统计模块
// 使用QChart实现可视化
QChartView* SalesAnalyzer::generateSalesChart() {
QBarSeries *series = new QBarSeries();
QSqlQuery query = dbManager->executeQuery(
"SELECT strftime('%Y-%m', sale_date) as month, SUM(amount) "
"FROM SalesRecord GROUP BY month"
);
while(query.next()) {
QBarSet *set = new QBarSet(query.value(0).toString());
*set << query.value1.todouble series->append(set);
}
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle("月度销售统计");
return new QChartView(chart);
}
4.2 XML报表生成
void ReportGenerator::exportToXML(const QDate& date) {
QDomDocument doc;
QDomProcessingInstruction instr = doc.createProcessingInstruction(
"xml", "version='1.0' encoding='UTF-8'");
doc.appendChild(instr);
QDomElement root = doc.createElement("SalesReport");
doc.appendChild(root);
QSqlQuery query = dbManager->executeQuery(
QString("SELECT * FROM SalesRecord WHERE sale_date >= '%1'")
.arg(date.toString(Qt::ISODate))
);
while(query.next()) {
QDomElement record = doc.createElement("Record");
record.setAttribute("id", query.value("record_id").toString());
QDomElement amount = doc.createElement("Amount");
amount.appendChild(doc.createTextNode(query.value("amount").toString()));
record.appendChild(amount);
root.appendChild(record);
}
QFile file("report.xml");
if(file.open(QIODevice::WriteOnly)) {
QTextStream stream(&file);
stream.setCodec("UTF-8");
doc.save(stream, 4);
}
}
4.3 打印功能实现
#include
#include
void printReport(const QString& htmlContent) {
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPageSize::A4);
QPrintDialog dialog(&printer);
if (dialog.exec() == QDialog::Accepted) {
QPainter painter;
painter.begin(&printer);
QTextDocument doc;
doc.setHtml(htmlContent);
doc.drawContents(&painter);
painter.end();
}
}
五、工程关键技术
5.1 多窗口管理策略
// 使用堆对象管理窗口生命周期
void MainController::showBrandManager() {
BrandManager* manager = new BrandManager(this); // 父对象自动管理内存
connect(manager, &BrandManager::closed,
[manager](){ manager->deleteLater(); });
manager->show();
}
5.2 国际化支持
# 在.pro文件中添加翻译支持
TRANSLATIONS += zh_CN.ts
QT += linguisttools
# 生成翻译文件
lupdate project.pro
linguist zh_CN.ts
lrelease zh_CN.ts
5.3 调试技巧
// 使用qDebug的格式化输出
qDebug().nospace()
<< "[SQL]" << query.lastQuery()
<< "\nBindings:" << query.boundValues();
// 启用SQL调试
QLoggingCategory::setFilterRules("qt.sql.*=true");
本项目源码:Qt开发CRM《汽车销售管理系统》_哔哩哔哩_bilibili
六、性能优化
- 数据库层面:
- 对sale_date字段建立索引
- 使用预编译语句(QSqlQuery::prepare)
- 界面渲染:
- 对大数据量使用QTableView的懒加载
- 启用OpenGL加速(QGraphicsView::setViewport)
- 内存管理:
- 使用QObject父子关系自动释放
- 对大型数据集采用分页加载
七、项目简历避坑指南:简历减分项清单
- "负责Qt界面开发" → "主导Qt MVVM架构重构,视图层与业务层解耦度达92%"
- "使用SQLite存储数据" → "设计SQLite分库分表方案,支撑1000+并发查询"
- "编写项目文档" → "产出32页《汽车销售数据合规白皮书》,通过ISO 27001审核