0


用QT链接SQL Server数据库制作交互界面(工资管理系统-数据库)

一、引言

  1. QT完整源代码贴在文末。入门文章,大佬可直接略过本篇。
  2. 本文仅介绍QT的使用心得以及快速上手的方法,需要读者有一点c++\c的基础,以及会SQL语言和SQL server数据库的使用。
  3. 题目为学校的数据库系统概论的期末专题训练。总用时两天半左右,第一天是QT的安装及了解,第二天继续了解+功能实现,最后半天给成品完善了一下功能和布局。
  4. 在整个过程中产生了许多疑问也走了一些弯路,因此写下此文,旨在帮助像我一样完全没接触过QT或交互界面的朋友快速上手,以制作出最后成品为导向。懂的并不多,如有错误欢迎指出。
  5. 以下是题目要求,不需要的朋友可以跳过:

系统实现:用QT/JAVA SWING/Tkinter等GUI框架开发数据库系统的交互界面。用SQL语言实现数据定义、数据查询和数据更新等操作并实现数据的持久化存储。

**题目三 工资管理系统的设计 **

系统概述:通过对人事管理管理部门中的职称、工资、员工、部门、工资类别等相关内容进行分析,完成具有人员管理、工资管理、部门管理等相关功能的小型数据库管理应用系统,系统需要具备增减工资中应发、应扣类别的灵活性以适应将来需求的变化。

基本要求

1.完成人员、部门、工资类别、职称表的维护

2.根据需要对工资类别进行添加 。

3.完成工资表的生成,并计算相关数据,进行查询。

4.按部门计算平均工资 。

5.按人、年统计平均工资 。

6.完成权限控制功能,如果一个同学独立完成,仅要求简单的用户登录即可。 本题目所需的知识点:E-R关系图、数据库表设计、数据库表维护等。

该题可2个同学完成,各同学题目为:

工资管理系统——基础数据

工资管理系统——工资管理

其中基础数据包括职称、工资、部门、工资类别、员工基本信息的录入、修改、删除、查询、打印。

工资管理包括工资的录入、删除、修改、查询、打印以及相关统计查询等。

二、QT各功能的介绍和解释

  1. 下载安装的方法csdn有很多,不再赘述。链接数据库前需要下载配置ODBC,也有很多文章。

1、QT的创建

  1. 整个项目只用得到创建项目和打开项目这两个按钮。
  2. 点击创建项目,选择第一个QT Widgets Applications,取个名选个路径,选择qmake,然后再base class这一栏选择QWidgetQMainwindow制作起来差不多,我选的是QWidget),然后有一个选择编译工具的,如果有多个就挑着选,都选也行,以创建后不报错为标准。最后一直点下一步直到完成创建。
  3. 此步也有很多教程,所以就简单几句话略过。

2、QT特点介绍:信号与槽

  1. QT中有一种特殊的概念,叫信号与槽。举个例子,当你在一个窗口上点击一个按钮时,这个按钮相当于向自己所在的界面发出了一个“我被点击了,我要进行相应的动作了”的信号,而槽就是接收这个信号的专门的接收器。可以理解为生物上的激素与受体。如果有读者用过MFC,那这个槽就是MFC中的点击事件。一个按钮(实际上是界面上所以可供交互的组件)相应的执行函数叫槽函数。

3、各文件的意义和交互的设计界面

  1. 点开源文件,双击widget.cpp开始我们的项目,主要的代码都写在这里。main.cpp暂时不用动。
  2. 此处通俗易懂地解释一下,main起的作用跟c++一样,不过在此项目里基本就起一个调出主交互页面(主页面的代码就在widget.cpp里)的作用,起这个作用的就一句话,点开来可以看到:w.show();
  3. 我们继续回到widget.cpp里。第一个类似函数体的大括号,为了简单易懂,我在此不严谨地称之为构造函数(确实有点像),我们的数据库的链接、控制界面的显示、对象和变量的定义新建、信号与槽函数(后面专门介绍)等都在这里进行定义,只有先在此定义了才能在后面使用。在这个文件里还需要写我们实现各种功能的函数,这些函数的定义写在相应的.h文件中,具体实现代码写在.cpp,跟c++一样。(具体形式我会在后面给出)

** 紧接着,我们进入到好玩的、可视化的部分!**

  1. 这也是和交互界面和平常编程的区别和乐趣所在。
  2. 左侧的目录里还有一个“界面文件”,点开,双击widget.ui,我们就会来到如下图所示的ui设计界面。

  1. 左边一列是各种组件,点击拖动到中间的界面上即可自由放置,拉拽四周的点可以放大缩小。右上角这一栏会显示你已经放置上的组件及其名字、属性。双击即可更改相应组件的名字,建议大家取一个自己记得住的名字便于区分。接下来我来简单介绍一下各个组件,以我的界面为例:

  1. 左右两侧的按钮,叫pushButton,在Buttons栏里,作用是点击后完成设定的动作,比如跳转新页面、显示数据等,具体需要自己设定。添加完按钮后系统会自动在.cpp文件中新建一个空的槽函数,我们右键添加的组件,选择“转到槽...”即可跳转到相应的槽函数进行编写。
  2. 中间的空白框是tableview,在Item Views栏,顾名思义是用来显示表格内容的,后续我们会链接数据库然后让数据库中的表在这个组件上显示出来。
  3. 接下来是界面上面:
  4. ![](https://img-blog.csdnimg.cn/direct/a5fcac76c24b4fbe9a513799b38e0791.png)
  5. 左边的文字点击后没有任何反应,它只是起到标识作用,是display widgets栏中的label组件。
  6. 右边则是一个可供输入的文本框,在input widget是中的line edit。它用来获取用户写在文本框里的内容,然后进行处理或者其他操作。
  7. 以上就是基础的组件及其用途,会使用他们已经可以完成很多窗口的设计了,也足够完成本系统。读者可自行探索更多不同功能的组件。

4、QT的代码应该如何写?写在哪?以什么方式写?

widget.h部分和widget.cpp中构造函数部分的代码

  1. 以下是我项目的widget.cpp中构造函数的源代码:
  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include "QMessageBox"
  4. #include "QSqlError"
  5. #include "QSqlQueryModel"
  6. #include <QtDebug>
  7. #include <QStandardItemModel>
  8. #include <QTableView>
  9. Widget::Widget(QWidget *parent)
  10. : QWidget(parent)
  11. , ui(new Ui::Widget)
  12. {
  13. ui->setupUi(this);
  14. userMode = new QSqlQueryModel(ui->tableView);//绑定
  15. QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
  16. db.setHostName("**********");//替换成自己的
  17. db.setDatabaseName("hhhh");
  18. // 使用 Windows 身份验证连接数据库
  19. db.setUserName(""); // 留空以使用 Windows 身份验证
  20. db.setPassword(""); // 留空以使用 Windows 身份验证
  21. if(db.open())
  22. {
  23. QMessageBox::information(this, "连接提示" ,"连接成功");
  24. }
  25. else
  26. {
  27. QMessageBox::warning(this, "连接提示" ,"连接失败");
  28. qDebug() << db.lastError().text(); // 输出错误信息
  29. }
  30. // 通过指针创建登录界面类的对象
  31. m_log = new login;
  32. // 调用登录窗口的show()函数显示登录界面
  33. m_log->show();
  34. m_register = new Lregister;
  35. // 建立信号槽,当接收到登录界面发来的login()信号后,调用主窗口的show()函数。
  36. connect(m_log,SIGNAL(log()),this,SLOT(show()));
  37. // 建立信号槽,当接收到登录界面发来的re()信号后,调用注册窗口的show()函数。
  38. connect(m_log,SIGNAL(re()),m_register,SLOT(show()));
  39. // 建立信号槽,当接收到注册界面发来的log2()信号后,调用主窗口的show()函数。
  40. connect(m_register,SIGNAL(log2()),this,SLOT(show()));
  41. // 建立信号槽,当接收到注册界面发来的close_window2()信号后,调用登录窗口的close()函数。
  42. connect(m_register,SIGNAL(close_window2()),m_log,SLOT(close()));
  43. m0 = new QSqlTableModel;
  44. m_statistics = new statistics;
  45. }
  46. Widget::~Widget()
  47. {
  48. delete ui;
  49. }
  50. //显示表employee的内容
  51. void Widget::on_pushButton_displayE_clicked()
  52. {
  53. m0->setTable("employee");
  54. ui->tableView->setModel(m0);
  55. m0->select();
  56. }
  57. //显示表department的内容
  58. void Widget::on_pushButton_displayD_clicked()
  59. {
  60. m0->setTable("department");
  61. ui->tableView->setModel(m0);
  62. m0->select();
  63. }
  64. //显示表profession的内容
  65. void Widget::on_pushButton_displayP_clicked()
  66. {
  67. m0->setTable("profession");
  68. ui->tableView->setModel(m0);
  69. m0->select();
  70. }
  71. //显示表Wcategory的内容
  72. void Widget::on_pushButton_displayW_clicked()
  73. {
  74. m0->setTable("Wcategory");
  75. ui->tableView->setModel(m0);
  76. m0->select();
  77. }
  78. //显示表wage的内容
  79. void Widget::on_pushButton_wage_clicked()
  80. {
  81. userMode->setQuery("UPDATE wage SET Rwage = Swage - Dwage");
  82. m0->setTable("wage");
  83. ui->tableView->setModel(m0);
  84. m0->select();
  85. }
  86. //查找查询的功能
  87. void Widget::on_pushButton_query_clicked()
  88. {
  89. QString item = ui->lineEdit_item->text() ;
  90. QString content = ui->lineEdit_content->text() ;
  91. QString str = QString('%1' + " = '%2'").arg(item).arg(content) ;
  92. userMode->setQuery("SELECT employee.name, employee.id, employee.gender, employee.birthday, employee.department, employee.profession, Wcategory.Wcategory, wage.year, wage.Rwage, wage.Swage, wage.Dwage from employee INNER JOIN wage ON wage.id = employee.id INNER JOIN Wcategory ON Wcategory.Wno = wage.Wno INNER JOIN department ON department.department = employee.department INNER JOIN profession ON profession.profession = employee.profession WHERE employee." + item + " = '" + content + "'");
  93. ui->tableView->setModel(userMode);
  94. }
  95. //删除所选中行的功能
  96. void Widget::on_pushButton_delete_clicked()
  97. {
  98. if(rights2 == "普通用户")
  99. {
  100. QMessageBox::information(this, "通知", "您无此权限!");
  101. }
  102. else if(rights2 == "管理员")
  103. {
  104. // 创建确认对话框
  105. QMessageBox::StandardButton reply;
  106. reply = QMessageBox::question(this, "确认", "您确定要对选中的行执行删除操作吗?", QMessageBox::Yes | QMessageBox::No);
  107. // 判断用户的选择
  108. if (reply == QMessageBox::Yes) {
  109. QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
  110. QModelIndexList selectedIndexes = selectionModel->selectedRows();
  111. QAbstractItemModel *model = ui->tableView->model();
  112. for (const QModelIndex &selectedIndex : selectedIndexes) {
  113. model->removeRow(selectedIndex.row());
  114. }
  115. ui->tableView->update();
  116. QMessageBox::information(this, "通知" ,"删除操作成功!");
  117. } else {
  118. QMessageBox::information(this, "通知" ,"删除操作已取消!");
  119. }
  120. }
  121. else if (rights2 == "")
  122. {
  123. QMessageBox::information(this, "通知" ,"rights2未赋值!");
  124. }
  125. }
  126. //退出的按钮
  127. void Widget::on_pushButton_exit_clicked()
  128. {
  129. exit(0);
  130. }
  131. //实现添加的按钮(增加空行)
  132. void Widget::on_pushButton_addrow_clicked()
  133. {
  134. if(rights2 == "管理员")
  135. {
  136. // 获取当前显示的表名
  137. QString tableName = m0->tableName();
  138. m0->setTable(tableName);
  139. ui->tableView->setModel(m0);
  140. m0->select();
  141. //加入空行
  142. m0->insertRow(m0->rowCount());
  143. m0->submitAll();
  144. }
  145. else
  146. {
  147. QMessageBox::information(this, "通知", "您无此权限!");
  148. }
  149. }
  150. //跳转到statistics统计界面的按钮
  151. void Widget::on_pushButton_statistics_clicked()
  152. {
  153. m_statistics->show();
  154. }
  155. //退出登录的按钮
  156. void Widget::on_pushButton_logout_clicked()
  157. {
  158. m_log->show();
  159. this->close();
  160. }
  1. 还有widget.h的完整代码(除了两条虚线之间以及#include部分,其他部分都是创建工程即有的,不需要改动):
  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include "login.h"
  4. #include "statistics.h"
  5. #include "Lregister.h"
  6. #include <QWidget>
  7. #include <QtSql/QSqlDatabase>
  8. #include <QMessageBox>
  9. #include <QSqlTableModel>
  10. #include <QSqlQuery>
  11. #include <QSqlQueryModel>
  12. #include <QSqlError>
  13. QT_BEGIN_NAMESPACE
  14. namespace Ui {
  15. class Widget;
  16. }
  17. QT_END_NAMESPACE
  18. class Widget : public QWidget
  19. {
  20. Q_OBJECT
  21. public:
  22. Widget(QWidget *parent = nullptr);
  23. ~Widget();
  24. //--------此处添加函数声明!!!!----------
  25. private slots:
  26. void on_pushButton_displayP_clicked();
  27. void on_pushButton_displayD_clicked();
  28. void on_pushButton_displayE_clicked();
  29. void on_pushButton_displayW_clicked();
  30. void on_pushButton_query_clicked();
  31. void on_pushButton_delete_clicked();
  32. void on_pushButton_add_clicked();
  33. void on_pushButton_wage_clicked();
  34. void on_pushButton_kindofwage_clicked();
  35. void on_pushButton_exit_clicked();
  36. void on_pushButton_addrow_clicked();
  37. void on_pushButton_statistics_clicked();
  38. void on_pushButton_logout_clicked();
  39. //--------此处添加函数声明!!!!----------
  40. //--------此处添加属性定义!!!!----------
  41. private:
  42. Ui::Widget *ui;
  43. QSqlQueryModel *userMode;
  44. QSqlTableModel *m0;
  45. QSqlTableModel *m1;
  46. QSqlTableModel *m2;
  47. QSqlTableModel *m3;
  48. QSqlTableModel *m4;
  49. QSqlTableModel *n0;
  50. QSqlTableModel *model;
  51. QSqlTableModel *tableView;
  52. QAbstractItemModel* tn;
  53. // 登录界面类的对象作为指针
  54. login * m_log;
  55. // 统计界面类的对象作为指针
  56. statistics * m_statistics;
  57. Lregister * m_register;
  58. //--------此处添加属性定义!!!!----------
  59. };
  60. #endif // WIDGET_H
  1. 以上涉及到的东西有:基本设定、定义与声明(包括信号与槽)、数据库的链接等。我们一个一个来介绍。
基本设定
  1. .cpp构造函数的代码中,ui->setupUi(this);这句就是对ui的操作,意思是建立ui。这句话一建立项目就有,不用改。
  2. userMode = new QSqlQueryModel(ui->tableView);//绑定
  3. 上面这句与我们的组件table view的设置有关,不加上这句没法用这个组件。但是需要在.h中添加相应声明(下面会说)。
  4. 可以理解为对使用组件所需要提前写下的基本设定。不需要懂为什么,只需要知道要用table view组件,就必须要这句话。推广开来,很多其他组件也都需要这样的设定。
定义与声明(包括信号与槽)
  1. C++一样,属性与成员函数声明写在.h文件,代码具体实现写在.cpp文件(构造函数后)。
  2. 例如,在.cpp里的一个函数,即一个按钮的槽函数on_pushButton_displayE_clicked(),它在.cpp里的代码如下:
  1. //显示表employee的内容
  2. void Widget::on_pushButton_displayE_clicked()
  3. {
  4. m0->setTable("employee");
  5. ui->tableView->setModel(m0);
  6. m0->select();
  7. }
  1. 以上函数中有一个对象m0,它是需要定义才能使用的。通常定义在**构造函数**的最后,也就是上面完整代码的倒数第二句话:m0 = new QSqlTableModel;
  2. 还有我们的信号与槽:
  1. // 建立信号槽,当接收到登录界面发来的login()信号后,调用主窗口的show()函数。
  2. connect(m_log,SIGNAL(log()),this,SLOT(show()));
  1. 这样形式的就是信号槽,用来接收其他部分发出的信号,然后做出反应。
  2. 格式是:**connect(发出信号的对象名,发出的信号名,接收信号的对象名,接收对象后做出反应的相应函数);**
  3. 上式中,m_log是我制作的登陆界面类的对象名字,发出的信号名叫log(),接收对象的就是现在这个widget窗口,所以是this,然后相应的事件函数名则是show(),即widget自带的一个函数:show(),作用是显示widget窗口。
  4. 整个语句的意思是:当对象m_log(也就是登陆界面)发出一个名叫log()的信号时,会被此窗口(widget)接收到,然后启动widget自带的函数show(),显示此窗口,实现一个登陆后展示主界面的效果。
  5. 当然,m_log也是需要在.h文件声明的,即上面.h完整代码中的 login * m_log; 句。我解释一下,这个login是我制作的登陆界面的文件名,就像widget。这句话的意思是,我定义了一个名字是m_log的、用来指代登录界面login的对象。可以把login看作一个类型,就像是stringcharint
  6. log()函数则是需要在login.cpp和.h中实现的。各个界面文件的实现方法都一样,不再赘述。这里在一个窗口的代码里出现另一个窗口的原因,则是我需要由一个窗口通过满足特定条件来引出另一个窗口。如果窗口数量多且每个窗口都可以引出另一个窗口,那么就可以像串糖葫芦串烧烤一样把他们串起来,甚至还可以变成一个“环”。网上,一些电脑中病毒后会源源不断地跳出新窗口来让电脑崩溃,或许就是这个原理,跟上面不同的是它的条件不需要点击按钮,可能是等待特定时间,比如0.5秒。但是想来应该没有这么简单,我对网安和黑客一窍不通。
数据库的链接
  1. 这部分没什么好说的,写在widget.cpp的构造函数位置。csdn上也有许多贴,照着来就行了,如果出错就多找经验贴。注意windows身份验证和用户名密码这两种方式的区分。

三、项目的整体实现思路

  1. 如图所示:

四、项目各功能思路详细说明

1、主界面

  1. ![](https://img-blog.csdnimg.cn/direct/4b60ab341c044374a9fc0bb3fb65c2f0.png)
  2. 主界面要实现的功能有以下:在tableview上显示各种表的内容、增、删、改、查、工资情况的自定义统计以及退出界面和退出登录(登出)。
  3. 显示各种表的内容的函数非常简单,以下是显示employee表按钮的槽函数:
  1. //显示表employee的内容
  2. void Widget::on_pushButton_displayE_clicked()
  3. {
  4. m0->setTable("employee");
  5. ui->tableView->setModel(m0);
  6. m0->select();
  7. }
  1. 显示其他表只需把“employee”换成其他的表名就可以了。
  2. 接下来是增、删、改、查。改最简单。我发现tableview本身是自带修改功能的,用法就是显示出表的内容后双击,然后直接修改就行。这个功能不需要写任何代码。如下图所示:

  1. 增加的功能我取了个巧。点击一个按钮实现添加一行空行的功能,然后利用上述修改的功能直接在空行里修改,这样就相当于添加了一行了。如果不想取巧,那么思路是将要添加的内容写在一个个lineEdit中,然后在类似“确定添加”的按钮槽函数中使用SQL语句将获取的lineEdit内容添加进数据库中。就结果而言这二者是一样的。
  2. 接下来是删除。点击表上一行的最左边,可以选中一整行,然后点击删除按钮进行删除。按钮的代码如下(添加了一个弹出对话框进行确认)。

  1. // 创建确认对话框
  2. QMessageBox::StandardButton reply;
  3. reply = QMessageBox::question(this, "确认", "您确定要对选中的行执行删除操作吗?", QMessageBox::Yes | QMessageBox::No);
  4. // 判断用户的选择
  5. if (reply == QMessageBox::Yes) {
  6. QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
  7. QModelIndexList selectedIndexes = selectionModel->selectedRows();
  8. QAbstractItemModel *model = ui->tableView->model();
  9. for (const QModelIndex &selectedIndex : selectedIndexes) {
  10. model->removeRow(selectedIndex.row());
  11. }
  12. ui->tableView->update();
  13. QMessageBox::information(this, "通知" ,"删除操作成功!");
  14. } else {
  15. QMessageBox::information(this, "通知" ,"删除操作已取消!");
  16. }
  1. 最后是查找。原理和添加的常规方法思路一样,不再赘述。源码我会贴在最后。
  2. 接下来是退出。退出界面的按键最简单,槽函数里就一句话:exit(0);
  3. 退出登录即登出,一登出就有登录,这里涉及到登录界面和注册界面的制作。还有工资情况的自定义统计,也涉及到一个新的界面。接下来介绍这两个界面。

2、登陆界面/注册界面

  1. 登录界面我命名为login,注册界面则为lregister

  1. 主要思路与添加功能相似。注册功能是在数据库中事先创建一个表,用来记录注册的用户名和密码。

  1. 将在lineEdit获取的用户名用SQL语句首先在库中查询是否注册过,若有,弹出提示,若无,就用户名和密码存储进去。
  2. 登录更为简单,只需将已输入的用户名和密码用SQL语句查找是否符合库中的记录。一致则登录。
  3. 这里还涉及到一个权限问题。我只将最初的第一个注册的用户(即管理员)的权限设为管理员,其他后来注册的都默认是普通用户。权限作为一个列名一起放入用户的数据库中。我对权限的设定是:管理员能使用所有功能,但是普通用户不能使用修改、添加和删除功能,只能查看与查找表的内容和工资情况统计。
  4. 对普通用户所能使用的功能的限制如何实现呢?我在普通用户不能使用的三个功能的函数里多加了一个if判断,判断此时用户是否是管理员。为此我设置了一个全局变量int rights = -1,放置在login.cppincldue后一行。当我登录时,程序会去寻找此时登录的用户的权限是什么,如果是管理员,则将rights赋值为1,普通用户则为0。同时,在相应限制功能的按钮槽函数中添加if判断,如果rights0,即普通用户,则弹出弹窗显示无权限(注意,此处跳出的弹窗是小弹窗,或者可以认为是系统环境内置的封装好的窗口,我们不需要自己写,如果想跳出自己写的窗口,则不能使用QMessageBox)。包含权限相关的登录按钮(在login.cpp中)代码如下:
  1. void login::on_pushButton_login_clicked()
  2. {
  3. // 从输入框获取账号
  4. QString username = ui->lineEdit_username->text();
  5. // 从输入框获取密码
  6. QString password = ui->lineEdit_password->text();
  7. QSqlQuery query;
  8. QSqlQuery query2;
  9. QString sql = "SELECT password FROM user_table WHERE username = '" + username + "'";
  10. if (!query.exec(sql)) {
  11. qDebug() << "无此账号!";
  12. return;
  13. }
  14. // 接下来,获取指定位置的数值并保存为QString类型
  15. if (query.next()) {
  16. QString value = query.value(0).toString();
  17. qDebug() << "密码数据找到了: " << value;
  18. //账号和密码匹配正确
  19. if (value == password)
  20. {
  21. QString sql2 = "SELECT rights FROM user_table WHERE username = '" + username + "'";
  22. if (!query2.exec(sql2)) {
  23. qDebug() << "查询语句错误!";
  24. return;
  25. }
  26. if (query2.next())
  27. {
  28. QString value2 = query2.value(0).toString();
  29. qDebug() << "用户权限找到了: " << value2;
  30. if(value2 == "管理员")
  31. {
  32. QMessageBox::information(this, "通知", "登录成功!您的权限是" + value2 + "权限!");
  33. rights = 1;
  34. rights2 = value2;
  35. }
  36. else if(value2 == "普通用户")
  37. {
  38. QMessageBox::information(this, "通知", "登录成功!您的权限是" + value2 + "权限!");
  39. rights = 0;
  40. rights2 = value2;
  41. }
  42. }
  43. else
  44. {
  45. qDebug() << "寻找权限时出错!";
  46. }
  47. emit(log());
  48. qDebug() << "已发送log信号";
  49. emit(close_window());
  50. }
  51. else // 账号或密码错误
  52. QMessageBox::information(this, "错误" ,"账号或密码错误!");
  53. } else {
  54. qDebug() << "寻找数据时出错!";
  55. }
  56. }
  1. 如何限制权限的代码以删除为例:
  1. //删除所选中行的功能
  2. void Widget::on_pushButton_delete_clicked()
  3. {
  4. if(rights2 == "普通用户")
  5. {
  6. QMessageBox::information(this, "通知", "您无此权限!");
  7. }
  8. else if(rights2 == "管理员")
  9. {
  10. // 创建确认对话框
  11. QMessageBox::StandardButton reply;
  12. reply = QMessageBox::question(this, "确认", "您确定要对选中的行执行删除操作吗?", QMessageBox::Yes | QMessageBox::No);
  13. // 判断用户的选择
  14. if (reply == QMessageBox::Yes) {
  15. QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
  16. QModelIndexList selectedIndexes = selectionModel->selectedRows();
  17. QAbstractItemModel *model = ui->tableView->model();
  18. for (const QModelIndex &selectedIndex : selectedIndexes) {
  19. model->removeRow(selectedIndex.row());
  20. }
  21. ui->tableView->update();
  22. QMessageBox::information(this, "通知" ,"删除操作成功!");
  23. } else {
  24. QMessageBox::information(this, "通知" ,"删除操作已取消!");
  25. }
  26. }
  27. else if (rights2 == "")
  28. {
  29. QMessageBox::information(this, "通知" ,"rights2未赋值!");
  30. }
  31. }
  1. 接下来还有2点很重要。1、如何在主界面前先显示登录界面;2、如何登录成功后跳出主界面(也就是widget界面),即如何使一个窗口拥有弹出另一个窗口的能力。
  2. 我们先将第二点。想要使一个窗口拥有弹出另一个窗口的能力很简单,即让被呼出的窗口在发起呼出动作的窗口里包含就行了。然后需要在发起呼出的界面的.h文件中声明一下,具体参见上文**定义与声明**的部分。
  3. 然后我们只需要一个发起动作的信号,来让新窗口跳出。具体使用的就是信号与槽,参见上文的定义与声明部分。请记得connect开头的那个语句要写在被调出的界面的.cpp里。
  4. 在发起呼出的界面.cpp中,我们需要一个语句来发出信号:
  1. emit(re());
  1. re()是一个函数名,可以自己定义。这个函数就是connect后面跟着的四个参数的第二个。
  2. 第一点,我需要先解释一下。我们点开man.cpp文件,我们可以看到有一句:
  1. w.show();
  1. 这句话的意思是,整个项目一启动,第一个跳出来的界面就是主界面widget,而不是我们想要的登陆界面。相应的解决办法是

3、统计界面

  1. 即工资情况的自定义统计界面,我命名为statistics

  1. 这有四个按钮,分别是四个模块,每个模块对应一个按钮,每个按钮点击后会弹出一个新的窗口。我把4个新窗口展示在下面。
  2. 年度平均工资界面,我命名为qyear

  1. 个人工资界面,我命名为qname

  1. 部门平均工资界面,我命名为qdepartment

  1. 职位平均工资界面,我命名为qprofession

  1. 这几个没什么好说的,跟查找功能一样,获取lineEdit内容然后在槽函数中进行查找然后处理运算,如何运算根据具体要求来。

五、补充

  1. 有一些针对用户体验的小细节我就没讲,读者要是有相应需求可以自行研究,比如进行重要操作时的确认弹窗、撤销功能、管理员可以对赋权限给普通用户的权限管理功能,还有记住密码功能。
  2. 还有一些很小的地方,但是对于用户体验来说不算小。比如在输入完成用户名和密码后,多数人习惯直接按下Enter回车键来代替鼠标对登录按钮的点击。
  3. 这些都是完全可以实现的,我因为时间不够,没有完全优化这些功能,但是可以给其中的一些功能提供简单的思路。
  4. 确认弹窗可以使用内置的QMessageBox
  5. 记住密码功能,可以创建一个txt文件,在登录时储存这次登录的用户名和密码,下次登录时可供读取。每次往里储存时记得比较一下是否和已经记载的数据一直,不一致则清空txt再进行储存。
  6. 权限管理功能本质上就是对数据库指定内容的修改。
  7. Enter键代替鼠标点击的实现csdn有帖子,不敢班门弄斧。

六、完整源码

  1. main.cpp:
  1. #include "widget.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. Widget w;
  7. //w.show();
  8. return a.exec();
  9. }
  1. widget.h:
  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include "login.h"
  4. #include "statistics.h"
  5. #include "Lregister.h"
  6. #include <QWidget>
  7. #include <QtSql/QSqlDatabase>
  8. #include <QMessageBox>
  9. #include <QSqlTableModel>
  10. #include <QSqlQuery>
  11. #include <QSqlQueryModel>
  12. #include <QSqlError>
  13. QT_BEGIN_NAMESPACE
  14. namespace Ui {
  15. class Widget;
  16. }
  17. QT_END_NAMESPACE
  18. class Widget : public QWidget
  19. {
  20. Q_OBJECT
  21. public:
  22. Widget(QWidget *parent = nullptr);
  23. ~Widget();
  24. private slots:
  25. void on_pushButton_displayP_clicked();
  26. void on_pushButton_displayD_clicked();
  27. void on_pushButton_displayE_clicked();
  28. void on_pushButton_displayW_clicked();
  29. void on_pushButton_query_clicked();
  30. void on_pushButton_delete_clicked();
  31. void on_pushButton_add_clicked();
  32. void on_pushButton_wage_clicked();
  33. void on_pushButton_kindofwage_clicked();
  34. void on_pushButton_exit_clicked();
  35. void on_pushButton_addrow_clicked();
  36. void on_pushButton_statistics_clicked();
  37. void on_pushButton_logout_clicked();
  38. private:
  39. Ui::Widget *ui;
  40. QSqlQueryModel *userMode;
  41. QSqlTableModel *m0;
  42. QSqlTableModel *m1;
  43. QSqlTableModel *m2;
  44. QSqlTableModel *m3;
  45. QSqlTableModel *m4;
  46. QSqlTableModel *n0;
  47. QSqlTableModel *model;
  48. QSqlTableModel *tableView;
  49. QAbstractItemModel* tn;
  50. // 登录界面类的对象作为指针
  51. login * m_log;
  52. // 统计界面类的对象作为指针
  53. statistics * m_statistics;
  54. Lregister * m_register;
  55. };
  56. #endif // WIDGET_H
  1. widget.cpp:
  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. #include "QMessageBox"
  4. #include "QSqlError"
  5. #include "QSqlQueryModel"
  6. #include <QtDebug>
  7. #include <QStandardItemModel>
  8. #include <QTableView>
  9. Widget::Widget(QWidget *parent)
  10. : QWidget(parent)
  11. , ui(new Ui::Widget)
  12. {
  13. ui->setupUi(this);
  14. userMode = new QSqlQueryModel(ui->tableView);//绑定
  15. QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
  16. db.setHostName("LAPTOP-PFEJR2BB");
  17. db.setDatabaseName("hhhh");
  18. // 使用 Windows 身份验证连接数据库
  19. db.setUserName(""); // 留空以使用 Windows 身份验证
  20. db.setPassword(""); // 留空以使用 Windows 身份验证
  21. if(db.open())
  22. {
  23. QMessageBox::information(this, "连接提示" ,"连接成功");
  24. }
  25. else
  26. {
  27. QMessageBox::warning(this, "连接提示" ,"连接失败");
  28. qDebug() << db.lastError().text(); // 输出错误信息
  29. }
  30. // 通过指针创建登录界面类的对象
  31. m_log = new login;
  32. // 调用登录窗口的show()函数显示登录界面
  33. m_log->show();
  34. m_register = new Lregister;
  35. // 建立信号槽,当接收到登录界面发来的login()信号后,调用主窗口的show()函数。
  36. connect(m_log,SIGNAL(log()),this,SLOT(show()));
  37. // 建立信号槽,当接收到登录界面发来的re()信号后,调用注册窗口的show()函数。
  38. connect(m_log,SIGNAL(re()),m_register,SLOT(show()));
  39. // 建立信号槽,当接收到注册界面发来的log2()信号后,调用主窗口的show()函数。
  40. connect(m_register,SIGNAL(log2()),this,SLOT(show()));
  41. // 建立信号槽,当接收到注册界面发来的close_window2()信号后,调用登录窗口的close()函数。
  42. connect(m_register,SIGNAL(close_window2()),m_log,SLOT(close()));
  43. m0 = new QSqlTableModel;
  44. m_statistics = new statistics;
  45. }
  46. Widget::~Widget()
  47. {
  48. delete ui;
  49. }
  50. //显示表employee的内容
  51. void Widget::on_pushButton_displayE_clicked()
  52. {
  53. m0->setTable("employee");
  54. ui->tableView->setModel(m0);
  55. m0->select();
  56. }
  57. //显示表department的内容
  58. void Widget::on_pushButton_displayD_clicked()
  59. {
  60. m0->setTable("department");
  61. ui->tableView->setModel(m0);
  62. m0->select();
  63. }
  64. //显示表profession的内容
  65. void Widget::on_pushButton_displayP_clicked()
  66. {
  67. m0->setTable("profession");
  68. ui->tableView->setModel(m0);
  69. m0->select();
  70. }
  71. //显示表Wcategory的内容
  72. void Widget::on_pushButton_displayW_clicked()
  73. {
  74. m0->setTable("Wcategory");
  75. ui->tableView->setModel(m0);
  76. m0->select();
  77. }
  78. //显示表wage的内容
  79. void Widget::on_pushButton_wage_clicked()
  80. {
  81. userMode->setQuery("UPDATE wage SET Rwage = Swage - Dwage");
  82. m0->setTable("wage");
  83. ui->tableView->setModel(m0);
  84. m0->select();
  85. }
  86. //查找查询的功能
  87. void Widget::on_pushButton_query_clicked()
  88. {
  89. QString item = ui->lineEdit_item->text() ;
  90. QString content = ui->lineEdit_content->text() ;
  91. QString str = QString('%1' + " = '%2'").arg(item).arg(content) ;
  92. userMode->setQuery("SELECT employee.name, employee.id, employee.gender, employee.birthday, employee.department, employee.profession, Wcategory.Wcategory, wage.year, wage.Rwage, wage.Swage, wage.Dwage from employee INNER JOIN wage ON wage.id = employee.id INNER JOIN Wcategory ON Wcategory.Wno = wage.Wno INNER JOIN department ON department.department = employee.department INNER JOIN profession ON profession.profession = employee.profession WHERE employee." + item + " = '" + content + "'");
  93. ui->tableView->setModel(userMode);
  94. }
  95. //删除所选中行的功能
  96. void Widget::on_pushButton_delete_clicked()
  97. {
  98. if(rights2 == "普通用户")
  99. {
  100. QMessageBox::information(this, "通知", "您无此权限!");
  101. }
  102. else if(rights2 == "管理员")
  103. {
  104. // 创建确认对话框
  105. QMessageBox::StandardButton reply;
  106. reply = QMessageBox::question(this, "确认", "您确定要对选中的行执行删除操作吗?", QMessageBox::Yes | QMessageBox::No);
  107. // 判断用户的选择
  108. if (reply == QMessageBox::Yes) {
  109. QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
  110. QModelIndexList selectedIndexes = selectionModel->selectedRows();
  111. QAbstractItemModel *model = ui->tableView->model();
  112. for (const QModelIndex &selectedIndex : selectedIndexes) {
  113. model->removeRow(selectedIndex.row());
  114. }
  115. ui->tableView->update();
  116. QMessageBox::information(this, "通知" ,"删除操作成功!");
  117. } else {
  118. QMessageBox::information(this, "通知" ,"删除操作已取消!");
  119. }
  120. }
  121. else if (rights2 == "")
  122. {
  123. QMessageBox::information(this, "通知" ,"rights2未赋值!");
  124. }
  125. }
  126. //退出的按钮
  127. void Widget::on_pushButton_exit_clicked()
  128. {
  129. exit(0);
  130. }
  131. //实现添加的按钮(增加空行)
  132. void Widget::on_pushButton_addrow_clicked()
  133. {
  134. if(rights2 == "管理员")
  135. {
  136. // 获取当前显示的表名
  137. QString tableName = m0->tableName();
  138. m0->setTable(tableName);
  139. ui->tableView->setModel(m0);
  140. m0->select();
  141. //加入空行
  142. m0->insertRow(m0->rowCount());
  143. m0->submitAll();
  144. }
  145. else
  146. {
  147. QMessageBox::information(this, "通知", "您无此权限!");
  148. }
  149. }
  150. //跳转到statistics统计界面的按钮
  151. void Widget::on_pushButton_statistics_clicked()
  152. {
  153. m_statistics->show();
  154. }
  155. //退出登录的按钮
  156. void Widget::on_pushButton_logout_clicked()
  157. {
  158. m_log->show();
  159. this->close();
  160. }
  1. login.h:
  1. #ifndef LOGIN_H
  2. #define LOGIN_H
  3. #include <QWidget>
  4. #include <QSqlQuery>
  5. #include <QMessageBox>
  6. extern int rights;
  7. extern QString rights2;
  8. namespace Ui {
  9. class login;
  10. }
  11. class login : public QWidget
  12. {
  13. Q_OBJECT
  14. public:
  15. explicit login(QWidget *parent = nullptr);
  16. ~login();
  17. signals:
  18. void log(); //登录主界面信号
  19. void close_window(); //关闭登录界面信号
  20. void re();
  21. private slots:
  22. void on_pushButton_login_clicked();
  23. void on_pushButton_exit_clicked();
  24. void on_pushButton_register_clicked();
  25. void on_pushButton_Lregister_clicked();
  26. private:
  27. Ui::login *ui;
  28. };
  29. #endif // LOGIN_H
  1. login,cpp:
  1. #include "login.h"
  2. #include "ui_login.h"
  3. #include <QMessageBox>
  4. int rights = -1;
  5. QString rights2 = "";
  6. login::login(QWidget *parent)
  7. : QWidget(parent)
  8. , ui(new Ui::login)
  9. {
  10. ui->setupUi(this);
  11. // 发出信号后关闭登录窗口的信号槽连接
  12. connect(this,SIGNAL(close_window()),this,SLOT(close()));
  13. ui->lineEdit_password->setEchoMode(QLineEdit::Password);//输入时显示圆点
  14. }
  15. login::~login()
  16. {
  17. delete ui;
  18. }
  19. void login::on_pushButton_login_clicked()
  20. {
  21. // 从输入框获取账号
  22. QString username = ui->lineEdit_username->text();
  23. // 从输入框获取密码
  24. QString password = ui->lineEdit_password->text();
  25. QSqlQuery query;
  26. QSqlQuery query2;
  27. QString sql = "SELECT password FROM user_table WHERE username = '" + username + "'";
  28. if (!query.exec(sql)) {
  29. qDebug() << "无此账号!";
  30. return;
  31. }
  32. // 接下来,获取指定位置的数值并保存为QString类型
  33. if (query.next()) {
  34. QString value = query.value(0).toString();
  35. qDebug() << "密码数据找到了: " << value;
  36. //账号和密码匹配正确
  37. if (value == password)
  38. {
  39. QString sql2 = "SELECT rights FROM user_table WHERE username = '" + username + "'";
  40. if (!query2.exec(sql2)) {
  41. qDebug() << "查询语句错误!";
  42. return;
  43. }
  44. if (query2.next())
  45. {
  46. QString value2 = query2.value(0).toString();
  47. qDebug() << "用户权限找到了: " << value2;
  48. if(value2 == "管理员")
  49. {
  50. QMessageBox::information(this, "通知", "登录成功!您的权限是" + value2 + "权限!");
  51. rights = 1;
  52. rights2 = value2;
  53. }
  54. else if(value2 == "普通用户")
  55. {
  56. QMessageBox::information(this, "通知", "登录成功!您的权限是" + value2 + "权限!");
  57. rights = 0;
  58. rights2 = value2;
  59. }
  60. }
  61. else
  62. {
  63. qDebug() << "寻找权限时出错!";
  64. }
  65. emit(log());
  66. qDebug() << "已发送log信号";
  67. emit(close_window());
  68. }
  69. else // 账号或密码错误
  70. QMessageBox::information(this, "错误" ,"账号或密码错误!");
  71. } else {
  72. qDebug() << "寻找数据时出错!";
  73. }
  74. }
  75. void login::on_pushButton_exit_clicked()
  76. {
  77. exit(0);
  78. }
  79. void login::on_pushButton_Lregister_clicked()
  80. {
  81. emit(re());
  82. qDebug() << "已发送re信号";
  83. }
  1. lregister.h:
  1. #ifndef LREGISTER_H
  2. #define LREGISTER_H
  3. #include <QWidget>
  4. #include <QString>
  5. #include <QSqlQuery>
  6. #include <QMessageBox>
  7. namespace Ui {
  8. class Lregister;
  9. }
  10. class Lregister : public QWidget
  11. {
  12. Q_OBJECT
  13. public:
  14. explicit Lregister(QWidget *parent = nullptr);
  15. ~Lregister();
  16. signals:
  17. void log2(); //登录主界面信号
  18. void close_window2(); //关闭注册界面和登录的信号
  19. void close_window3(); //只关闭注册界面的信号
  20. private slots:
  21. void on_pushButton_register_clicked();
  22. void on_pushButton_cancel_clicked();
  23. private:
  24. Ui::Lregister *ui;
  25. };
  26. #endif // LREGISTER_H
  1. lregister.cpp:
  1. #include "lregister.h"
  2. #include "ui_lregister.h"
  3. Lregister::Lregister(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Lregister)
  6. {
  7. ui->setupUi(this);
  8. // 发出信号后关闭注册窗口的信号槽连接
  9. connect(this,SIGNAL(close_window2()),this,SLOT(close()));
  10. // 发出信号后关闭注册窗口的信号槽连接
  11. connect(this,SIGNAL(close_window3()),this,SLOT(close()));
  12. ui->lineEdit_password->setEchoMode(QLineEdit::Password);//输入时显示圆点
  13. ui->lineEdit_Apassword->setEchoMode(QLineEdit::Password);//输入时显示圆点
  14. }
  15. Lregister::~Lregister()
  16. {
  17. delete ui;
  18. }
  19. void Lregister::on_pushButton_register_clicked()
  20. {
  21. // 从输入框获取账号
  22. QString username = ui->lineEdit_username->text();
  23. // 从输入框获取密码
  24. QString password = ui->lineEdit_password->text();
  25. // 从输入框获取确认密码
  26. QString Apassword = ui->lineEdit_Apassword->text();
  27. QSqlQuery query;
  28. QSqlQuery query2;
  29. QString sql = "SELECT password FROM user_table WHERE username = '" + username + "'";
  30. QString sql2 = "INSERT INTO user_table (username, password, rights) VALUES ('" + username + "', '" + password +"', '普通用户');";
  31. if (query.exec(sql))
  32. {
  33. if (!query.next())
  34. {
  35. qDebug() << "此用户名不重复,可以注册! ";
  36. if(password == Apassword)
  37. {
  38. if (query2.exec(sql2))
  39. {
  40. QMessageBox::information(this, "通知", "注册成功!权限为普通用户权限!");
  41. // 创建确认对话框
  42. QMessageBox::StandardButton reply;
  43. reply = QMessageBox::question(this, "选择", "您想现在登录此账号吗?", QMessageBox::Yes | QMessageBox::No);
  44. // 判断用户的选择
  45. if (reply == QMessageBox::Yes)
  46. {
  47. emit(log2());
  48. qDebug() << "已发送log2信号";
  49. emit(close_window2());
  50. }
  51. else
  52. {
  53. emit(close_window2());
  54. }
  55. }
  56. else
  57. {
  58. QMessageBox::information(this, "通知", "注册失败!");
  59. }
  60. }
  61. else
  62. {
  63. QMessageBox::information(this, "通知", "确认密码与密码不一致!请重新输入!");
  64. }
  65. }
  66. else
  67. {
  68. QMessageBox::information(this, "通知", "sql2语句错误!");
  69. }
  70. }
  71. else
  72. {
  73. QMessageBox::information(this, "通知", "sql语句错误!");
  74. }
  75. }
  76. void Lregister::on_pushButton_cancel_clicked()
  77. {
  78. emit(close_window3());
  79. }
  1. staistics.h:
  1. #ifndef STATISTICS_H
  2. #define STATISTICS_H
  3. #include <QWidget>
  4. #include "qyear.h"
  5. #include "qname.h"
  6. #include "qdepartment.h"
  7. #include "qprofession.h"
  8. namespace Ui {
  9. class statistics;
  10. }
  11. class statistics : public QWidget
  12. {
  13. Q_OBJECT
  14. public:
  15. explicit statistics(QWidget *parent = nullptr);
  16. ~statistics();
  17. private slots:
  18. void on_pushButton_Qyear_clicked();
  19. void on_pushButton_Qname_clicked();
  20. void on_pushButton_Qdepartment_clicked();
  21. void on_pushButton_Qprofession_clicked();
  22. private:
  23. Ui::statistics *ui;
  24. // 按年份统计界面类的对象作为指针
  25. Qyear * m_Qyear;
  26. // 按人统计界面类的对象作为指针
  27. Qname * m_Qname;
  28. // 按部门统计界面类的对象作为指针
  29. Qdepartment * m_Qdepartment;
  30. // 按职位统计界面类的对象作为指针
  31. Qprofession * m_Qprofession;
  32. };
  33. #endif // STATISTICS_H

statistics.cpp:

  1. #include "statistics.h"
  2. #include "ui_statistics.h"
  3. statistics::statistics(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::statistics)
  6. {
  7. ui->setupUi(this);
  8. m_Qyear = new Qyear;
  9. m_Qname = new Qname;
  10. m_Qdepartment = new Qdepartment;
  11. m_Qprofession = new Qprofession;
  12. }
  13. statistics::~statistics()
  14. {
  15. delete ui;
  16. }
  17. void statistics::on_pushButton_Qyear_clicked()
  18. {
  19. m_Qyear->show();
  20. }
  21. void statistics::on_pushButton_Qname_clicked()
  22. {
  23. m_Qname->show();
  24. }
  25. void statistics::on_pushButton_Qdepartment_clicked()
  26. {
  27. m_Qdepartment->show();
  28. }
  29. void statistics::on_pushButton_Qprofession_clicked()
  30. {
  31. m_Qprofession->show();
  32. }
  1. qyear.h:
  1. #ifndef QYEAR_H
  2. #define QYEAR_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class Qyear;
  6. }
  7. class Qyear : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit Qyear(QWidget *parent = nullptr);
  12. ~Qyear();
  13. private slots:
  14. void on_pushButton_clicked();
  15. private:
  16. Ui::Qyear *ui;
  17. };
  18. #endif // QYEAR_H
  1. qyear.cpp:
  1. #include "qyear.h"
  2. #include "ui_qyear.h"
  3. #include <QMessageBox>
  4. #include <QSqlQuery>
  5. #include <QSqlQueryModel>
  6. Qyear::Qyear(QWidget *parent)
  7. : QWidget(parent)
  8. , ui(new Ui::Qyear)
  9. {
  10. ui->setupUi(this);
  11. }
  12. Qyear::~Qyear()
  13. {
  14. delete ui;
  15. }
  16. void Qyear::on_pushButton_clicked()
  17. {
  18. QString year = ui->lineEdit_year->text();
  19. QSqlQuery query;
  20. if (!year.isEmpty()) {
  21. query.prepare("SELECT 4*AVG(Rwage) AS avg_wage "
  22. "FROM wage "
  23. "JOIN Wcategory ON wage.Wno = Wcategory.Wno "
  24. "JOIN employee ON wage.id = employee.id "
  25. "WHERE wage.year = '" + year + "' ");
  26. }
  27. else
  28. {
  29. QMessageBox::warning(this, "错误" ,"请输入年份!");
  30. }
  31. if (!query.exec()) {
  32. QMessageBox::critical(this, "错误", "查询失败!");
  33. return;
  34. }
  35. // 获取结果并显示到lineEdit_result中
  36. if (query.next()) {
  37. QString averageWage = query.value("avg_wage").toString();
  38. ui->lineEdit_result->setText(averageWage);
  39. QMessageBox::information(this, year + "年的人均总工资",
  40. QString( year + "年的人均总工资为:%1")
  41. .arg(averageWage));
  42. }
  43. else
  44. {
  45. QMessageBox::information(this, "错误", "找不到结果!错误!");
  46. }
  47. }
  1. qname.h:
  1. #ifndef QNAME_H
  2. #define QNAME_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class Qname;
  6. }
  7. class Qname : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit Qname(QWidget *parent = nullptr);
  12. ~Qname();
  13. private slots:
  14. void on_pushButton_clicked();
  15. private:
  16. Ui::Qname *ui;
  17. };
  18. #endif // QNAME_H
  1. qname.cpp:
  1. #include "qname.h"
  2. #include "ui_qname.h"
  3. #include <QMessageBox>
  4. #include <QSqlQuery>
  5. #include <QSqlQueryModel>
  6. Qname::Qname(QWidget *parent)
  7. : QWidget(parent)
  8. , ui(new Ui::Qname)
  9. {
  10. ui->setupUi(this);
  11. }
  12. Qname::~Qname()
  13. {
  14. delete ui;
  15. }
  16. void Qname::on_pushButton_clicked()
  17. {
  18. QString name = ui->lineEdit_name->text();
  19. QSqlQuery query;
  20. if (!name.isEmpty()) {
  21. query.prepare("SELECT sum(Rwage) AS avg_wage "
  22. "FROM wage "
  23. "JOIN Wcategory ON wage.Wno = Wcategory.Wno "
  24. "JOIN employee ON wage.id = employee.id "
  25. "WHERE employee.name = '" + name + "' ");
  26. }
  27. else
  28. {
  29. QMessageBox::warning(this, "错误" ,"请输入员工姓名!");
  30. }
  31. if (!query.exec()) {
  32. QMessageBox::critical(this, "错误", "查询失败!");
  33. return;
  34. }
  35. // 获取结果并显示到lineEdit_result中
  36. if (query.next()) {
  37. QString averageWage = query.value("avg_wage").toString();
  38. ui->lineEdit_result->setText(averageWage);
  39. QMessageBox::information(this, "员工" + name + "的年均总工资",
  40. QString("员工" + name + "的年均总工资为: %1")
  41. .arg(averageWage));
  42. }
  43. else
  44. {
  45. QMessageBox::information(this, "错误", "找不到结果!错误!");
  46. }
  47. }
  1. qdepartment.h:
  1. #ifndef QDEPARTMENT_H
  2. #define QDEPARTMENT_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class Qdepartment;
  6. }
  7. class Qdepartment : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit Qdepartment(QWidget *parent = nullptr);
  12. ~Qdepartment();
  13. private slots:
  14. void on_pushButton_clicked();
  15. private:
  16. Ui::Qdepartment *ui;
  17. };
  18. #endif // QDEPARTMENT_H
  1. qdepartment.cpp:
  1. #include "qdepartment.h"
  2. #include "ui_qdepartment.h"
  3. #include <QMessageBox>
  4. #include <QSqlQuery>
  5. #include <QSqlQueryModel>
  6. Qdepartment::Qdepartment(QWidget *parent)
  7. : QWidget(parent)
  8. , ui(new Ui::Qdepartment)
  9. {
  10. ui->setupUi(this);
  11. }
  12. Qdepartment::~Qdepartment()
  13. {
  14. delete ui;
  15. }
  16. void Qdepartment::on_pushButton_clicked()
  17. {
  18. QString department = ui->lineEdit_department->text();
  19. QSqlQuery query;
  20. if (!department.isEmpty()) {
  21. query.prepare("SELECT 4*AVG(Rwage) AS avg_wage "
  22. "FROM wage "
  23. "JOIN Wcategory ON wage.Wno = Wcategory.Wno "
  24. "JOIN employee ON wage.id = employee.id "
  25. "WHERE employee.department = '" + department + "' ");
  26. }
  27. else
  28. {
  29. QMessageBox::warning(this, "错误" ,"请输入部门!");
  30. }
  31. if (!query.exec()) {
  32. QMessageBox::critical(this, "错误", "查询失败!");
  33. return;
  34. }
  35. // 获取结果并显示到lineEdit_result中
  36. if (query.next()) {
  37. QString averageWage = query.value("avg_wage").toString();
  38. ui->lineEdit_result->setText(averageWage);
  39. QMessageBox::information(this, department + " 部门的人均年均总工资",
  40. QString( department + " 部门的人均年均总工资为: %1")
  41. .arg(averageWage));
  42. }
  43. else
  44. {
  45. QMessageBox::information(this, "错误", "找不到结果!错误!");
  46. }
  47. }
  1. qprofession.h:
  1. #ifndef QPROFESSION_H
  2. #define QPROFESSION_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class Qprofession;
  6. }
  7. class Qprofession : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit Qprofession(QWidget *parent = nullptr);
  12. ~Qprofession();
  13. private slots:
  14. void on_pushButton_clicked();
  15. private:
  16. Ui::Qprofession *ui;
  17. };
  18. #endif // QPROFESSION_H
  1. qprofession.cpp:
  1. #include "qprofession.h"
  2. #include "ui_qprofession.h"
  3. #include <QMessageBox>
  4. #include <QSqlQuery>
  5. #include <QSqlQueryModel>
  6. Qprofession::Qprofession(QWidget *parent)
  7. : QWidget(parent)
  8. , ui(new Ui::Qprofession)
  9. {
  10. ui->setupUi(this);
  11. }
  12. Qprofession::~Qprofession()
  13. {
  14. delete ui;
  15. }
  16. void Qprofession::on_pushButton_clicked()
  17. {
  18. QString profession = ui->lineEdit_profession->text();
  19. QSqlQuery query;
  20. if (!profession.isEmpty()) {
  21. query.prepare("SELECT 4*AVG(Rwage) AS avg_wage "
  22. "FROM wage "
  23. "JOIN Wcategory ON wage.Wno = Wcategory.Wno "
  24. "JOIN employee ON wage.id = employee.id "
  25. "WHERE employee.profession = '" + profession + "' ");
  26. }
  27. else
  28. {
  29. QMessageBox::warning(this, "错误" ,"请输入职位!");
  30. }
  31. if (!query.exec()) {
  32. QMessageBox::critical(this, "错误", "查询失败!");
  33. return;
  34. }
  35. // 获取结果并显示到lineEdit_result中
  36. if (query.next()) {
  37. QString averageWage = query.value("avg_wage").toString();
  38. ui->lineEdit_result->setText(averageWage);
  39. QMessageBox::information(this, profession + " 职位的人均年均总工资",
  40. QString( profession + " 职位的人均年均总工资为: %1")
  41. .arg(averageWage));
  42. }
  43. else
  44. {
  45. QMessageBox::information(this, "错误", "找不到结果!错误!");
  46. }
  47. }
  1. 各个窗口我都是直接拖组件然后调大小,没有使用代码进行修改,因此只放图片。
  2. 登录界面login

  1. 注册界面lregister

  1. 主界面widget

  1. 工资统计界面statistics

  1. 年度平均工资界面qyear

  1. 个人工资qname

  1. 部门平均工资qdepartment

  1. 职位平均工资qprofession

七、结语

  1. 再次声明,本篇仅是为了初学QT的朋友快速上手而作,大佬可直接忽略此文。写下此文也是想记录一下自己制作的心路历程,毕竟是自己第一次接触类似ui的东西,也对这种窗口的制作产生了兴趣。
  2. 谨以此文,纪念自己大学前两年半的计算机所学。希望未来我能在自己感兴趣的领域越走越远,越走越深,也希望未来的自己回望一生时,不会因虚度年华而悔恨。愿常有书籍电影相伴,常有知己相知,常有爱人相爱。
标签: 数据库 qt 交互

本文转载自: https://blog.csdn.net/qq_65449388/article/details/136140409
版权归原作者 飞檐流丹 所有, 如有侵权,请联系我们删除。

“用QT链接SQL Server数据库制作交互界面(工资管理系统-数据库)”的评论:

还没有评论