基于QT、MySQL的电子词典

数据结构课程设计

(一)需求和规格说明

问题描述:设计一个中英文字典查询系统。如给出中文“苹果”,能查询出其对应的英文单词“apple”。

编程任务:

1)自建系统的词库和存储结构,以方便更好的进行查询;

2)该系统在一定的权限控制下具有基本的查询、增加、删除、修改功能,并尽可能的保证良好的时间开销;

(1)查询操作时应考虑精确查询和模糊查询;

(2)增加操作时:该程序输入一个英语单词,若该单词不存在,可向词库添加该词和释义(应考虑一个单词可以有多个释义);

3)实现输入输出交互界面。

(二)设计

1.问题分析

对于构建课设要求的电子词库,我们必须解决以下几个问题,

  1. 数据的存储(2)数据的增删改查(3)美观的交互界面

我们来进行逐个分析:

(1)数据的存储:我首先想到的是使用红黑树,即C++STL中的map容器,其具有高性能的查找功能,存储方面也可以单独建立一个词库文件,利用C++文档流读取文件来创建我们的词库红黑树,这确实是一个可选择项。

不过本次课设的最终方案还是选择了MySQL数据库作为存储策略,目的是学习搭建QT调用mysql的环境、在QT中进行SQL的增删改查操作,而且使用数据库比较方便,我也可以在mysql的图形化编辑工具DataGrip中实时地查看词库建立地情况,对于一个电子词典的编辑是非常便利的。

当然,首要问题其实是环境的配置,没有在QT中导入mysql的话就什么都做不了。我们需要利用对应版本QT源码文件夹插件包中有关于sql驱动“sqldriver”插件库下的mysql.pro文件进行代码修改,将mysql服务的路径导入,并构筑工程文件,从而构建起QT与mysql的动态链接库.dll文件,再将同等级路径下生成的动态链接库文件放入QT的插件文件夹下,才能满足后续的编译需求。这一部分我会在答辩视频中进行详细的讲解。

环境配置后,就是怎么在QT中调用mysql进行数据的增删改查,这本质是第(2)个问题,而第(1)个问题中我们亟待解决的问题仍然有如下几个:
第一步:建立自己的词库数据集,我先是在百度文档中查找到了《大学英语词汇库》将其导入execl文件中,通过execl的操作将其整理成两列。其中一列是英文,另一列则是它的翻译。然后通过execl的拼接函数CONCAT批量化生成SQL插入语句,并用DataGrip在我的数据库中新建一个dictionary表,并将生成的插入语句全部执行,全部插入到dictionary表中。这样就完成了数据集的搭建。


使用execl批量生成SQL插入语句。

在DG中将批量生成的SQL语句全部执行插入。

   SQL语句执行完毕,我们就完成了数据集的构建,词库的导入,之后就可以使用SQL语句来不断进行维护了。

数据的增删改查:

数据的增删改查,我们选择在QT中执行SQL语句,这里就涉及到SQL的导入,

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

        db.setHostName("127.0.0.1");  //连接本地主机,也可以写localhost,或写电脑域名。

        db.setPort(3306);

        db.setDatabaseName("test");

        db.setUserName("dictionary");//grant all on test.* to 'dictionary'@'%';所有权限已给

        db.setPassword("2394485232");//密码就是作者的QQ哒

我们通过QsqlDatabase类来实例化一个数据库对象,用来链接我的MySQL,这里我已经在DG中创建了一个可以在任意别的主机打开的用户,并且授予了该用户对于我的test数据库的增删改查全部权限。

下面分模块并结合UI界面进行课设作品的介绍与代码实现:

首先我们再看一遍题目要求:

1)自建系统的词库和存储结构,以方便更好的进行查询;

2)该系统在一定的权限控制下具有基本的查询、增加、删除、修改功能,并尽可能的保证良好的时间开销;

(1)查询操作时应考虑精确查询和模糊查询;

(2)增加操作时:该程序输入一个英语单词,若该单词不存在,可向词库添加该词和释义(应考虑一个单词可以有多个释义);

3)实现输入输出交互界面。



题目要求简洁,主界面如上所示,其mainwindow代码实现则如下:

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)

    : QMainWindow(parent)

    , ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    setWindowTitle("dictionary_ver_wyuu");

    ui->lineEdit->setFont(QFont("宋体",13));

    ui->pushButton->setFont(QFont("宋体",12));

//    ui->pushButton_2->setFont(QFont("宋体",13));

//    ui->pushButton_3->setFont(QFont("宋体",13));

//    ui->pushButton_4->setFont(QFont("宋体",13));

//    ui->pushButton_5->setFont(QFont("宋体",13));

    ui->textBrowser->setFont(QFont("宋体",11));

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

        db.setHostName("127.0.0.1");  //连接本地主机,也可以写localhost,或写电脑域名。

        db.setPort(3306);

        db.setDatabaseName("test");

        db.setUserName("dictionary");//grant all on test.* to 'dictionary'@'%';所有权限已给

        db.setPassword("2394485232");//密码就是作者的QQ哒

        bool ok =

        db.open();

        if (ok){

            QMessageBox::information(this, "提示", "服务器连接成功");

        }

        else {

            QMessageBox::information(this, "提示", "服务器连接失败");

            qDebug()<<"error open database because"<<db.lastError().text();

        }

}

MainWindow::~MainWindow()

{

    delete ui;

    db.close();

}

<1>在翻译按钮实现的槽函数中,是这样的逻辑设计,先利用我们强大的正则表达式来检测输入的字符串中有没有汉字,然后根据输入的汉字还是英文分为两种处理模式,其中如果输入的是汉字,会用%占位符来进行模糊搜索的实现。

QString target ="'%"+ ui->lineEdit->text() +"%'";

QString sql = "select * from dictionary where translation like "+ target;

而输入的是英语,就不会考虑到模糊搜索而是直接拼接好需要的SQL语句并进行执行。

QString target ="'"+ ui->lineEdit->text() +"'";

QString sql = "select * from dictionary where English = "+ target;

搜索到的结果通过

while (query.next()) {

            qDebug()<<  query.value(1).toString()

                     <<  query.value(2).toString();

             English = query.value(1).toString();

             translation = query.value(2).toString();

             qDebug()<< English;

             qDebug()<< translation;

        }

来进行获取,并打印在UI界面的文本框内。

整体槽函数代码如下:

void MainWindow::on_pushButton_clicked()

{

    QString targetline = ui->lineEdit->text();

    bool b = targetline.contains(QRegExp("[\\x4e00-\\x9fa5]+"));

    QSqlQuery query(db);

    if(b)

    {

        //qDebug()<<"存在中文";

        QString target ="'%"+ ui->lineEdit->text() +"%'";

        QString sql = "select * from dictionary where translation like "+ target;

        qDebug()<< sql;

        query.exec(sql);

        QString English="";

        QString translation="";

        while (query.next()) {

            qDebug()<<  query.value(1).toString()

                     <<  query.value(2).toString();

             English = query.value(1).toString();

             translation = query.value(2).toString();

             qDebug()<< English;

             qDebug()<< translation;

        }

        if(English=="")

        {

            ui->textBrowser->append("抱歉,词库中暂时没有,欢迎您编辑该词条!");

        }

        ui->textBrowser->append(English);

        ui->textBrowser->append(translation);

    }

    else

    {

    QString target ="'"+ ui->lineEdit->text() +"'";

    QString sql = "select * from dictionary where English = "+ target;

    query.exec(sql);

    QString English="";

    QString translation="";

    while (query.next()) {

        qDebug()<<  query.value(1).toString()

                 <<  query.value(2).toString();

         English = query.value(1).toString();

         translation = query.value(2).toString();

    }

    if(English=="")

    {

        ui->textBrowser->append("抱歉,词库中暂时没有,欢迎您编辑该词条!");

    }

    ui->textBrowser->append(English);

    ui->textBrowser->append(translation);

    }

}

<2>清空

void MainWindow::on_pushButton_2_clicked()

{

    ui->lineEdit->setText("");

    ui->textBrowser->setText("");

}

<3>打开增加词条界面

void MainWindow::on_pushButton_3_clicked()

{

    update_vocabulary * configWindow = new update_vocabulary;

    configWindow->show();

}

<4>打开删除词条界面

void MainWindow::on_pushButton_4_clicked()

{

    fix_vocabulary * configWindow2 = new fix_vocabulary;

    configWindow2->show();

}

<5>打开修改词条界面

void MainWindow::on_pushButton_5_clicked()

{

    modify_vocabulary * configWindow3 = new modify_vocabulary;

    configWindow3->show();

}

后面的3、4、5其实就是打开一个新界面,下面对3、4、5点进行分点详细论述介绍。

首先是3,增加词条:

在增加词条中,实现底层逻辑就是获取用户在文本框内输入的文本,然后进行一定的字符串拼接方式,拼接成插入的SQL语句。



SQL的插入,即为INSERT INTO关键字来实现,其实与我在数据存入时是一样的语法

其代码实现如下(为节省篇幅,在构造函数中连接MySQL与UI相关不再显示)

void update_vocabulary::on_pushButton_clicked()

{

    QSqlQuery query(db);

    QString English = ui->lineEdit->text();

    QString translation = ui->lineEdit_2->text();

    QString sql = "insert into dictionary(English,translation) values('" +English+ "','"+translation+"')";

    query.exec(sql);

    this->close();

}

就是简单的获取两个参数,然后拼接成一条SQL语句来执行。

query.exec(sql);

4是删除词条

删除词条使用的SQL语句是:

其关键字为DELETE。

Ui界面如下:


如果删除我的数据库中没有的词条,会导致闪退,其代码实现如下:(为节省篇幅,在构造函数中连接MySQL与UI相关不再显示)

void fix_vocabulary::on_pushButton_clicked()

{

            QString target ="'"+ ui->lineEdit->text() +"'";

            qDebug()<<target;

            QSqlQuery query(db);

            QString sql = "delete from dictionary where English = "+ target;

            qDebug()<<sql;

            query.exec(sql);

            this->close();

}

在文本框中获取目标词条的英文用来定位,然后使用DELETE关键字拼接为删除指令的SQL语句执行即可。

5.修改词条

修改词条使用的SQL语句是:

使用的关键字是UPDATE 。

UI界面如下:


代码逻辑是通过最上面的文本框来获取英文,然后在下面的两个文本框进行修改,其实现代码如下

void modify_vocabulary::on_pushButton_clicked()

{

    QSqlQuery query(db);

    QString former ="'"+ ui->lineEdit->text() + "'";

    QString English2 = "'"+ui->lineEdit_2->text()+ "'";

    QString translation ="'"+ ui->lineEdit_3->text()+"'";

    //update employee set dept_id=3 where id=3;

    QString sql = "update dictionary set English = "+ English2 + " where English = "+ former;

    query.exec(sql);

    QString sql2 = "update dictionary set translation = "+ translation + "where English = "+ former;

    query.exec(sql2);

    this->close();

}

总之这里就是拼接了SQL语句执行,写课设报告时发现这里两句应该可以并作一句,这样还可以提高执行效率,代码需要进一步的优化!

总之这里也是拼成了SQL语句去执行。

三个小模块是一模一样的逻辑。

以上就是(2)和(3)的设计总体介绍。

2.设计思想


(1)首先构思一下该软件的各个方面的大致实现,以及规划一下需要设计的模块。文件架构如下:

其中在QT的插件库中还需要有MySQL驱动的动态链接库文件。

这两个动态链接库文件是必要放在QT插件库下的。

总的来说C:\Qt\Qt5.14.2\5.14.2\mingw73_64\plugins\sqldrivers文件下应该是有这五个动态链接库的

不然就无法完成环境的配置。

其余问题其实都已经在问题分析中做过详细阐述了,我将在答辩视频中做进一步汇报。

(三)用户手册

(1)程序需要借由MySQL服务器运行,在使用该程序前,请确保您的主机上具备MySQL服务。

(2)其他提示可以参考UI界面的tips

Tips:

修改词条:在最上方文本框中输入目标词条的英文用来在数据库中定位此词条,然后在下方两个文本框中分别添加修改后的英文及其译文。

Tips:

删除词条:在下面的文本框中输入目标词条英文,点击删除词条即可

请不要删除数据库中没有的词条,当你查到某个词条觉得它不合理的时候再考虑删除并修改

等..

( 3 ) 作者初学MySQL,程序实现可能不尽如人意,只能实现基本的增删改查,没有像代码输入时的用户提示功能或是扩展搜索框功能,后续我会继续努力,争取添加这些效果的。

(四)调试及测试

1. 部分程序运行截图

主界面截图:

修改词条界面截图:

删除词条界面截图:



修改词条界面截图:

  1. 测试数据

目前共收录3083个词,其实还远远不够,可以考虑继续收集数据,扩充数据集。


3. 测试结果

支持模糊搜索,而且时间效率较高。

4. 进一步改进

(1)数据集较小,词汇量不够大。

(2)不支持扩展搜索框以及提示工具。

(3)对于用户的门槛较高,要求对方也具备MySQL提供的服务。之后可以考虑嵌入式开发(开玩笑的,就是一个U盘),来存储数据集。

 (五) 感想

在这次课设中用到的技术栈对于我来说还真是不少的,老师也对我说一旦牵扯到实际开发对技术的要求就是这样的,我也深有感悟,虽然这样一个小项目确实不能算是到达实际开发的门槛,而且我实现的项目也存在一些问题,但是我真的收获了很多新的知识,包括我用整整三天的时间,学习了SQL操作的基础篇,也就是增删改查。确实这个项目用到的SQL语句的逻辑其实都是最基础的。并没有涉及到分页查询和多表联查中的内连接、外连接、联合查询、子查询等复杂的查询语法,也没有涉及到并发事务处理等业务逻辑,但是作为对于我数据库学习的一个小总结我认为是可以的,因为它也确实帮助我加深了对于SQL语法的记忆,比方说DCL语言,这一部分我在听课的时候是没有着重去听的,但是后来做项目的过程中发现DCL是必不可少要熟练使用的。

总而言之,完成这样一个小项目是比较自豪激动的,感谢老师特地留下这么一个感想板块T-T。

附录:

代码量并不多,且基本已在问题分析环节展现

#include "mainwindow.h"

#include "ui_mainwindow.h"



MainWindow::MainWindow(QWidget *parent)

    : QMainWindow(parent)

    , ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    setWindowTitle("dictionary_ver_wyuu");

    ui->lineEdit->setFont(QFont("宋体",13));

    ui->pushButton->setFont(QFont("宋体",12));

//    ui->pushButton_2->setFont(QFont("宋体",13));

//    ui->pushButton_3->setFont(QFont("宋体",13));

//    ui->pushButton_4->setFont(QFont("宋体",13));

//    ui->pushButton_5->setFont(QFont("宋体",13));

    ui->textBrowser->setFont(QFont("宋体",11));

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

        db.setHostName("127.0.0.1");  //连接本地主机,也可以写localhost,或写电脑域名。

        db.setPort(3306);

        db.setDatabaseName("test");

        db.setUserName("dictionary");//grant all on test.* to 'dictionary'@'%';所有权限已给

        db.setPassword("2394485232");//密码就是作者的QQ哒

        bool ok =

        db.open();

        if (ok){

            QMessageBox::information(this, "提示", "服务器连接成功");

        }

        else {

            QMessageBox::information(this, "提示", "服务器连接失败");

            qDebug()<<"error open database because"<<db.lastError().text();

        }

}



MainWindow::~MainWindow()

{

    delete ui;

    db.close();

}





void MainWindow::on_pushButton_clicked()

{

    QString targetline = ui->lineEdit->text();

    bool b = targetline.contains(QRegExp("[\\x4e00-\\x9fa5]+"));

    QSqlQuery query(db);

    if(b)

    {

        //qDebug()<<"存在中文";

        QString target ="'%"+ ui->lineEdit->text() +"%'";

        QString sql = "select * from dictionary where translation like "+ target;

        qDebug()<< sql;

        query.exec(sql);

        QString English="";

        QString translation="";

        while (query.next()) {

            qDebug()<<  query.value(1).toString()

                     <<  query.value(2).toString();

             English = query.value(1).toString();

             translation = query.value(2).toString();

             qDebug()<< English;

             qDebug()<< translation;

        }

        if(English=="")

        {

            ui->textBrowser->append("抱歉,词库中暂时没有,欢迎您编辑该词条!");

        }

        ui->textBrowser->append(English);

        ui->textBrowser->append(translation);

    }

    else

    {

    QString target ="'"+ ui->lineEdit->text() +"'";

    QString sql = "select * from dictionary where English = "+ target;

    query.exec(sql);

    QString English="";

    QString translation="";

    while (query.next()) {

        qDebug()<<  query.value(1).toString()

                 <<  query.value(2).toString();

         English = query.value(1).toString();

         translation = query.value(2).toString();

    }

    if(English=="")

    {

        ui->textBrowser->append("抱歉,词库中暂时没有,欢迎您编辑该词条!");

    }

    ui->textBrowser->append(English);

    ui->textBrowser->append(translation);

    }

}



void MainWindow::on_pushButton_2_clicked()

{

    ui->lineEdit->setText("");

    ui->textBrowser->setText("");



}



void MainWindow::on_pushButton_3_clicked()

{

    update_vocabulary * configWindow = new update_vocabulary;

    configWindow->show();

}



void MainWindow::on_pushButton_4_clicked()

{

    fix_vocabulary * configWindow2 = new fix_vocabulary;

    configWindow2->show();

}



void MainWindow::on_pushButton_5_clicked()

{

    modify_vocabulary * configWindow3 = new modify_vocabulary;

    configWindow3->show();

}



    

#include "fix_vocabulary.h"

#include "ui_fix_vocabulary.h"



fix_vocabulary::fix_vocabulary(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::fix_vocabulary)

{

    ui->setupUi(this);

    setWindowTitle("编辑词条");

    ui->lineEdit->setFont(QFont("宋体",13));

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

        db.setHostName("127.0.0.1");  //连接本地主机,也可以写localhost,或写电脑域名。

        db.setPort(3306);

        db.setDatabaseName("test");

        db.setUserName("dictionary");

        db.setPassword("2394485232");

        db.open();

}



fix_vocabulary::~fix_vocabulary()

{

    delete ui;

    db.close();

}



void fix_vocabulary::on_pushButton_clicked()

{

            QString target ="'"+ ui->lineEdit->text() +"'";

            qDebug()<<target;

            QSqlQuery query(db);

            QString sql = "delete from dictionary where English = "+ target;

            qDebug()<<sql;

            query.exec(sql);

            this->close();

}

#include "modify_vocabulary.h"

#include "ui_modify_vocabulary.h"



modify_vocabulary::modify_vocabulary(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::modify_vocabulary)

{

    ui->setupUi(this);

    ui->lineEdit_2->setFont(QFont("宋体",13));

    ui->lineEdit_3->setFont(QFont("宋体",13));

    ui->lineEdit->setFont(QFont("宋体",13));

    setWindowTitle("编辑词条");

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

        db.setHostName("127.0.0.1");  //连接本地主机,也可以写localhost,或写电脑域名。

        db.setPort(3306);

        db.setDatabaseName("test");

        db.setUserName("dictionary");

        db.setPassword("2394485232");

        db.open();

}



modify_vocabulary::~modify_vocabulary()

{

    delete ui;

}



void modify_vocabulary::on_pushButton_clicked()

{

    QSqlQuery query(db);

    QString former ="'"+ ui->lineEdit->text() + "'";

    QString English2 = "'"+ui->lineEdit_2->text()+ "'";

    QString translation ="'"+ ui->lineEdit_3->text()+"'";

    //update employee set dept_id=3 where id=3;

    QString sql = "update dictionary set English = "+ English2 + " where English = "+ former;

    query.exec(sql);

    QString sql2 = "update dictionary set translation = "+ translation + "where English = "+ former;

    query.exec(sql2);

    this->close();

}



#include "update_vocabulary.h"

#include "ui_update_vocabulary.h"



update_vocabulary::update_vocabulary(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::update_vocabulary)

{

    ui->setupUi(this);

    setWindowTitle("编辑词条");

       ui->lineEdit->setFont(QFont("宋体",13));

       ui->lineEdit_2->setFont(QFont("宋体",13));

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

        db.setHostName("127.0.0.1");  //连接本地主机,也可以写localhost,或写电脑域名。

        db.setPort(3306);

        db.setDatabaseName("test");

        db.setUserName("dictionary");

        db.setPassword("2394485232");

        db.open();

}



update_vocabulary::~update_vocabulary()

{

    delete ui;

    db.close();

}



void update_vocabulary::on_pushButton_clicked()

{

    QSqlQuery query(db);

    QString English = ui->lineEdit->text();

    QString translation = ui->lineEdit_2->text();

    QString sql = "insert into dictionary(English,translation) values('" +English+ "','"+translation+"')";

    query.exec(sql);

    this->close();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值