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 主窗口布局
主窗口采用分割布局设计,左侧为联系人列表,右侧为详情面板:
cpp
// 主窗口布局结构
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
Ui::MainWindow *ui; // UI界面对象
ContactDialog *contactDialog; // 联系人编辑对话框
QSqlDatabase db; // 数据库连接
QSqlTableModel *contactModel; // 数据模型
};
1.2 联系人对话框设计
联系人编辑对话框采用表单布局,包含完整的联系人信息输入字段:
cpp
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 数据验证机制
为电话号码和邮箱地址添加格式验证:
cpp
// 电话号码验证
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作为轻量级数据库,自动创建数据库文件和表结构:
cpp
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作为视图:
cpp
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 添加联系人
通过对话框收集用户输入,验证数据后插入数据库:
cpp
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 编辑联系人
获取选中行的数据,在对话框中显示并允许用户修改:
cpp
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 删除联系人
安全删除机制,包含确认对话框防止误删:
cpp
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 多字段模糊搜索
支持姓名、电话、邮箱、地址、备注的模糊匹配:
cpp
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 实时搜索更新
通过信号槽机制实现搜索结果的实时更新:
cpp
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格式文件:
cpp
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文件导入联系人数据:
cpp
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 界面交互连接
通过信号槽机制实现界面组件之间的通信:
cpp
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 表格选择变化处理
实时更新详情面板显示选中联系人的信息:
cpp
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文件中配置项目依赖:
qmake
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp \
contactdialog.cpp
HEADERS += \
mainwindow.h \
contactdialog.h
FORMS += \
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学习有所帮助!如有问题,欢迎在评论区讨论。
相关资源: