当前位置: 首页 > news >正文

Qt个人通讯录项目开发教程 - 从零开始构建联系人管理系统

Qt个人通讯录项目开发教程 - 从零开始构建联系人管理系统

项目概述

本项目是一个基于Qt框架开发的个人通讯录管理系统,具有完整的联系人CRUD操作、搜索功能和数据导入导出功能。项目采用C++语言开发,使用Qt的SQL模块实现数据持久化,通过MVC架构模式实现界面与数据的分离。

项目特点:

  • 📱 现代化界面设计,操作简洁直观
  • 💾 SQLite数据库存储,数据安全可靠
  • 🔍 多字段模糊搜索功能
  • 📤 支持CSV格式数据导入导出
  • ✅ 完整的数据验证机制
  • 🎯 MVC架构设计,代码结构清晰
  • 📋 详情面板实时显示联系人信息

源代码下载: https://download.csdn.net/download/weixin_42059464/91707072

技术栈

  • 开发语言: C++
  • GUI框架: Qt 5/6
  • 数据库: SQLite
  • 开发工具: Qt Creator
  • 编译器: 支持C++11及以上版本
  • 操作系统: 跨平台(Windows、macOS、Linux)

项目结构

10_PersonalContactList/
├── 10_PersonalContactList.pro    # Qt项目配置文件
├── main.cpp                      # 程序入口文件
├── mainwindow.h                  # 主窗口类头文件
├── mainwindow.cpp                # 主窗口类实现文件
├── mainwindow.ui                 # 主窗口UI设计文件
├── contactdialog.h               # 联系人对话框头文件
└── contactdialog.cpp             # 联系人对话框实现文件

核心功能实现

1. 界面设计

在这里插入图片描述

1.1 主窗口布局

主窗口采用分割布局设计,左侧为联系人列表,右侧为详情面板:

// 主窗口布局结构
class MainWindow : public QMainWindow
{Q_OBJECTprivate:Ui::MainWindow *ui;           // UI界面对象ContactDialog *contactDialog; // 联系人编辑对话框QSqlDatabase db;              // 数据库连接QSqlTableModel *contactModel; // 数据模型
};
1.2 联系人对话框设计

联系人编辑对话框采用表单布局,包含完整的联系人信息输入字段:

void ContactDialog::setupUI()
{QVBoxLayout *mainLayout = new QVBoxLayout(this);// 创建表单组QGroupBox *formGroup = new QGroupBox("联系人信息");QGridLayout *formLayout = new QGridLayout(formGroup);// 姓名输入框QLabel *nameLabel = new QLabel("姓名:");nameEdit = new QLineEdit;nameEdit->setPlaceholderText("请输入姓名");formLayout->addWidget(nameLabel, 0, 0);formLayout->addWidget(nameEdit, 0, 1);// 电话号码输入框(带验证器)QLabel *phoneLabel = new QLabel("电话号码:");phoneEdit = new QLineEdit;phoneEdit->setPlaceholderText("请输入电话号码");QRegExp phoneRegex("^[0-9\\-\\+\\s\\(\\)]{0,20}$");phoneEdit->setValidator(new QRegExpValidator(phoneRegex, this));formLayout->addWidget(phoneLabel, 1, 0);formLayout->addWidget(phoneEdit, 1, 1);
}
1.3 数据验证机制

为电话号码和邮箱地址添加格式验证:

// 电话号码验证
bool MainWindow::isValidPhoneNumber(const QString &phone)
{QRegExp phoneRegex("^[0-9\\-\\+\\s\\(\\)]{7,20}$");return phoneRegex.exactMatch(phone);
}// 邮箱格式验证
bool MainWindow::isValidEmail(const QString &email)
{QRegExp emailRegex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");return emailRegex.exactMatch(email);
}

2. 数据库设计与实现

2.1 SQLite数据库初始化

使用SQLite作为轻量级数据库,自动创建数据库文件和表结构:

void MainWindow::setupDatabase()
{// 创建SQLite数据库db = QSqlDatabase::addDatabase("QSQLITE");// 设置数据库文件路径QString dbPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);QDir().mkpath(dbPath);db.setDatabaseName(dbPath + "/contacts.db");if (!db.open()) {QMessageBox::critical(this, "错误", "无法打开数据库: " + db.lastError().text());return;}// 创建联系人表QSqlQuery query;query.exec("CREATE TABLE IF NOT EXISTS contacts (""id INTEGER PRIMARY KEY AUTOINCREMENT,""name TEXT NOT NULL,""phone TEXT NOT NULL,""email TEXT,""address TEXT,""notes TEXT"")");
}
2.2 MVC架构实现

使用QSqlTableModel作为数据模型,QTableView作为视图:

void MainWindow::setupTable()
{// 创建数据模型contactModel = new QSqlTableModel(this, db);contactModel->setTable("contacts");contactModel->setEditStrategy(QSqlTableModel::OnManualSubmit);// 设置表头contactModel->setHeaderData(0, Qt::Horizontal, "ID");contactModel->setHeaderData(1, Qt::Horizontal, "姓名");contactModel->setHeaderData(2, Qt::Horizontal, "电话");contactModel->setHeaderData(3, Qt::Horizontal, "邮箱");contactModel->setHeaderData(4, Qt::Horizontal, "地址");contactModel->setHeaderData(5, Qt::Horizontal, "备注");// 设置表格视图ui->contactTableWidget->setModel(contactModel);ui->contactTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);ui->contactTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
}

3. CRUD操作实现

3.1 添加联系人

通过对话框收集用户输入,验证数据后插入数据库:

void MainWindow::addContact()
{if (!contactDialog) {contactDialog = new ContactDialog(this);}contactDialog->setContactInfo("", "", "", "", "");contactDialog->setWindowTitle("添加联系人");if (contactDialog->exec() == QDialog::Accepted) {QSqlRecord record = contactModel->record();record.setValue("name", contactDialog->getName());record.setValue("phone", contactDialog->getPhone());record.setValue("email", contactDialog->getEmail());record.setValue("address", contactDialog->getAddress());record.setValue("notes", contactDialog->getNotes());if (contactModel->insertRecord(-1, record)) {contactModel->submitAll();showStatusMessage("联系人添加成功");contactModel->select();} else {QMessageBox::warning(this, "错误", "添加联系人失败: " + contactModel->lastError().text());}}
}
3.2 编辑联系人

获取选中行的数据,在对话框中显示并允许用户修改:

void MainWindow::editContact()
{QModelIndex currentIndex = ui->contactTableWidget->currentIndex();if (!currentIndex.isValid()) {QMessageBox::information(this, "提示", "请先选择一个联系人");return;}int row = currentIndex.row();QSqlRecord record = contactModel->record(row);if (!contactDialog) {contactDialog = new ContactDialog(this);}contactDialog->setContactInfo(record.value("name").toString(),record.value("phone").toString(),record.value("email").toString(),record.value("address").toString(),record.value("notes").toString());contactDialog->setWindowTitle("编辑联系人");if (contactDialog->exec() == QDialog::Accepted) {record.setValue("name", contactDialog->getName());record.setValue("phone", contactDialog->getPhone());record.setValue("email", contactDialog->getEmail());record.setValue("address", contactDialog->getAddress());record.setValue("notes", contactDialog->getNotes());if (contactModel->setRecord(row, record)) {contactModel->submitAll();showStatusMessage("联系人更新成功");contactModel->select();}}
}
3.3 删除联系人

安全删除机制,包含确认对话框防止误删:

void MainWindow::deleteContact()
{QModelIndex currentIndex = ui->contactTableWidget->currentIndex();if (!currentIndex.isValid()) {QMessageBox::information(this, "提示", "请先选择一个联系人");return;}int row = currentIndex.row();QSqlRecord record = contactModel->record(row);QString name = record.value("name").toString();QMessageBox::StandardButton reply = QMessageBox::question(this, "确认删除", QString("确定要删除联系人 '%1' 吗?").arg(name),QMessageBox::Yes | QMessageBox::No);if (reply == QMessageBox::Yes) {if (contactModel->removeRow(row)) {contactModel->submitAll();showStatusMessage("联系人删除成功");contactModel->select();}}
}

4. 搜索功能实现

4.1 多字段模糊搜索

支持姓名、电话、邮箱、地址、备注的模糊匹配:

void MainWindow::searchContacts()
{QString searchText = ui->searchLineEdit->text().trimmed();if (searchText.isEmpty()) {contactModel->setFilter("");showStatusMessage("显示所有联系人");contactModel->select();clearDetailPanel();return;}QString filter = QString("name LIKE '%%1%' OR phone LIKE '%%1%' OR email LIKE '%%1%' OR address LIKE '%%1%' OR notes LIKE '%%1%'").arg(searchText);contactModel->setFilter(filter);contactModel->select();showStatusMessage(QString("找到 %1 个匹配的联系人").arg(contactModel->rowCount()));updateDetailPanelForIndex(ui->contactTableWidget->currentIndex());
}
4.2 实时搜索更新

通过信号槽机制实现搜索结果的实时更新:

void MainWindow::setupConnections()
{// 搜索功能连接connect(ui->searchLineEdit, &QLineEdit::textChanged, this, &MainWindow::searchContacts);connect(ui->clearSearchButton, &QPushButton::clicked, this, &MainWindow::clearSearch);// 表格选择变化connect(ui->contactTableWidget->selectionModel(), &QItemSelectionModel::currentRowChanged,this, &MainWindow::onCurrentRowChanged);
}

5. 数据导入导出功能

5.1 CSV格式导出

将联系人数据导出为CSV格式文件:

void MainWindow::exportContacts()
{QString fileName = QFileDialog::getSaveFileName(this, "导出联系人", "contacts.csv", "CSV文件 (*.csv)");if (fileName.isEmpty()) return;QFile file(fileName);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {QMessageBox::warning(this, "错误", "无法创建文件");return;}QTextStream out(&file);out.setCodec("UTF-8");// 写入表头out << "姓名,电话,邮箱,地址,备注\n";// 写入数据for (int row = 0; row < contactModel->rowCount(); ++row) {QSqlRecord record = contactModel->record(row);out << QString("\"%1\",\"%2\",\"%3\",\"%4\",\"%5\"\n").arg(record.value("name").toString()).arg(record.value("phone").toString()).arg(record.value("email").toString()).arg(record.value("address").toString()).arg(record.value("notes").toString());}file.close();showStatusMessage("联系人导出成功");
}
5.2 CSV格式导入

从CSV文件导入联系人数据:

void MainWindow::importContacts()
{QString fileName = QFileDialog::getOpenFileName(this, "导入联系人", "", "CSV文件 (*.csv)");if (fileName.isEmpty()) return;QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {QMessageBox::warning(this, "错误", "无法打开文件");return;}QTextStream in(&file);in.setCodec("UTF-8");// 跳过表头QString header = in.readLine();int importedCount = 0;while (!in.atEnd()) {QString line = in.readLine();QStringList fields = parseCSVLine(line);if (fields.size() >= 2) { // 至少需要姓名和电话QSqlRecord record = contactModel->record();record.setValue("name", fields[0]);record.setValue("phone", fields[1]);record.setValue("email", fields.size() > 2 ? fields[2] : "");record.setValue("address", fields.size() > 3 ? fields[3] : "");record.setValue("notes", fields.size() > 4 ? fields[4] : "");if (contactModel->insertRecord(-1, record)) {importedCount++;}}}contactModel->submitAll();contactModel->select();file.close();showStatusMessage(QString("成功导入 %1 个联系人").arg(importedCount));
}

6. 信号槽机制

6.1 界面交互连接

通过信号槽机制实现界面组件之间的通信:

void MainWindow::setupConnections()
{// CRUD操作按钮connect(ui->addButton, &QPushButton::clicked, this, &MainWindow::addContact);connect(ui->editButton, &QPushButton::clicked, this, &MainWindow::editContact);connect(ui->deleteButton, &QPushButton::clicked, this, &MainWindow::deleteContact);// 搜索功能connect(ui->searchLineEdit, &QLineEdit::textChanged, this, &MainWindow::searchContacts);connect(ui->clearSearchButton, &QPushButton::clicked, this, &MainWindow::clearSearch);// 表格交互connect(ui->contactTableWidget, &QTableView::doubleClicked, this, &MainWindow::onTableDoubleClicked);connect(ui->contactTableWidget->selectionModel(), &QItemSelectionModel::currentRowChanged,this, &MainWindow::onCurrentRowChanged);// 菜单操作connect(ui->actionImport, &QAction::triggered, this, &MainWindow::importContacts);connect(ui->actionExport, &QAction::triggered, this, &MainWindow::exportContacts);
}
6.2 表格选择变化处理

实时更新详情面板显示选中联系人的信息:

void MainWindow::onCurrentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{Q_UNUSED(previous)updateDetailPanelForIndex(current);
}void MainWindow::updateDetailPanelForIndex(const QModelIndex &index)
{if (!index.isValid()) {clearDetailPanel();return;}QSqlRecord record = contactModel->record(index.row());ui->detailNameLabel->setText(record.value("name").toString());ui->detailPhoneLabel->setText(record.value("phone").toString());ui->detailEmailLabel->setText(record.value("email").toString());ui->detailAddressLabel->setText(record.value("address").toString());ui->detailNotesLabel->setText(record.value("notes").toString());
}

开发环境搭建

1. 安装Qt开发环境

  1. 下载并安装Qt Creator
  2. 配置编译器(推荐使用MinGW或MSVC)
  3. 创建新的Qt Widgets Application项目

2. 项目配置

在.pro文件中配置项目依赖:

QT       += core gui sqlgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11SOURCES += \main.cpp \mainwindow.cpp \contactdialog.cppHEADERS += \mainwindow.h \contactdialog.hFORMS += \mainwindow.ui

3. 编译运行

  1. 在Qt Creator中打开项目
  2. 配置构建套件
  3. 点击运行按钮编译并执行程序

项目特色功能

1. 智能数据验证

  • 电话号码格式验证
  • 邮箱地址格式验证
  • 必填字段检查

2. 实时搜索

  • 多字段模糊匹配
  • 实时结果显示
  • 搜索状态提示

3. 数据持久化

  • SQLite数据库存储
  • 自动创建数据库文件
  • 数据安全可靠

4. 用户友好界面

  • 详情面板实时显示
  • 状态栏消息提示
  • 确认对话框防止误操作

5. 数据导入导出

  • CSV格式支持
  • 批量数据处理
  • 编码格式处理

扩展功能建议

1. 高级搜索功能

  • 按分组搜索
  • 按生日搜索
  • 按标签搜索

2. 联系人分组

  • 创建联系人分组
  • 分组管理功能
  • 分组统计信息

3. 生日提醒

  • 生日提醒功能
  • 日历集成
  • 提醒设置

4. 数据备份

  • 自动备份功能
  • 云端同步
  • 数据恢复

5. 界面美化

  • 主题切换
  • 自定义样式
  • 动画效果

性能优化建议

1. 数据库优化

  • 添加索引提高查询性能
  • 使用事务处理批量操作
  • 定期清理无用数据

2. 内存管理

  • 使用智能指针管理动态内存
  • 避免不必要的对象拷贝
  • 及时释放资源

3. 界面优化

  • 虚拟化大列表显示
  • 延迟加载详情信息
  • 异步处理耗时操作

常见问题解决

1. 编译错误

问题: 找不到Qt SQL模块
解决: 在.pro文件中添加 QT += sql

2. 运行时错误

问题: 数据库连接失败
解决: 检查数据库文件路径和权限

3. 数据导入问题

问题: CSV文件编码错误
解决: 确保文件使用UTF-8编码

总结

本项目展示了Qt框架在桌面应用开发中的强大功能,通过合理的架构设计和数据库集成,构建了一个功能完整、界面友好的个人通讯录管理系统。项目涵盖了Qt开发的核心技术点:

  • MVC架构: 使用QSqlTableModel实现数据模型
  • 数据库操作: SQLite数据库的创建和管理
  • 界面设计: 表单布局和对话框设计
  • 信号槽机制: 实现界面组件间的通信
  • 数据验证: 输入数据的格式验证
  • 文件操作: CSV格式的导入导出
  • 错误处理: 完善的异常处理机制

这个项目适合作为Qt数据库应用开发的入门项目,也可以在此基础上扩展更多功能,如联系人分组、生日提醒、数据同步等高级特性。

希望这个教程对您的Qt学习有所帮助!如有问题,欢迎在评论区讨论。


相关资源:

  • Qt官方文档
  • Qt SQL模块文档
  • SQLite官方文档
  • CSV格式规范
http://www.dtcms.com/a/338892.html

相关文章:

  • 【运维进阶】Ansible 角色管理
  • 【自动化运维神器Ansible】Playbook调用Role详解:从入门到精通
  • 数字孪生 :提高制造生产力的智能方法
  • 红日靶场03
  • 【Qt】 数据库连接池
  • B站 韩顺平 笔记 (Day 23)
  • LG P3710 方方方的数据结构 Solution
  • 【Qt开发】常用控件(五)
  • DzzOffice版权信息修改教程
  • 遥感amp;机器学习入门实战教程 | Sklearn 案例③:PCA + SVM / 随机森林 对比与调参
  • CSDN 创始人蒋涛:以开源驱动技术创新,拥抱黄金十年
  • LeetCode100-560和为K的子数组
  • 开源 C++ QT Widget 开发(二)基本控件应用
  • leetcode_ 76 最小覆盖子串
  • 决策树(续)
  • 大数据技术栈 —— Redis与Kafka
  • 字符串与算法题详解:最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密
  • 磨砂玻璃登录页面使用教程 v0.1.1
  • 【Linux仓库】进程创建与进程终止【进程·柒】
  • 通过C#上位机串口写入和读取浮点数到stm32的片内flash实战4(通过串口下发AD9833设置值并在上位机显示波形曲线)
  • 基于单片机智能点滴输液系统
  • 元素的width和offsetWidth有什么区别
  • java八股文-中间件-参考回答
  • Win11家庭版docker安装MaxKB
  • 【论文阅读】DETR3D: 3D Object Detection from Multi-view Images via 3D-to-2D Queries
  • 边缘智能体:Go编译在医疗IoT设备端运行轻量AI模型(中)
  • 【HTML】3D动态凯旋门
  • 【SpringBoot】15 核心功能 - Web开发原理 - 请求处理 - 常用请求参数注解
  • 【SpringBoot】Dubbo、Zookeeper
  • 【完整源码+数据集+部署教程】鳄梨表面缺陷检测图像分割系统源码和数据集:改进yolo11-MLCA