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 ¤t, 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开发环境
- 下载并安装Qt Creator
- 配置编译器(推荐使用MinGW或MSVC)
- 创建新的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. 编译运行
- 在Qt Creator中打开项目
- 配置构建套件
- 点击运行按钮编译并执行程序
项目特色功能
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格式规范