前言
课程设计用的是vfp,但是我对vfp很不感冒。但是没办法,硬着头皮写吧。我这里先写个python草稿
之前接单的时候有过很类似的项目,可以说是一模一样,由于写过一次我觉得还是没有难度的
题目分析
程序必须实现的功能如下:
- 登陆(查)
- 车辆信息管理(增删改查)
- 驾驶员信息管理(增删改查)
- 投诉信息管理(表连接,增删改查)
- 驾驶员信息浏览(查)
- 投诉信息浏览(查)
- 用户权限管理(查)
- CS架构(mysql服务器作为server端,client端直接处理返回的数据即可,不必另做server端)
程序实现
登陆模块
很简单就能实现
流程图
ui设计
这里我用我自己以前接单的项目掏了一个登陆和注册ui过来,名字为"login.ui"
登陆模块如下
注册模块如下
然后用pyuic转换一下,生成ui的py代码
代码实现
ui代码
创建一个py文件,命名为main
from login import Ui_MainWindow1
from PyQt5.QtWidgets import QApplication, QMainWindow,QMessageBox,QGroupBox,QHeaderView,QMenu,QAbstractItemView
from PyQt5.QtGui import QIcon,QStandardItemModel,QStandardItem,QCursor
from PyQt5.Qt import QThread, pyqtSignal,QSize,QColor,QBrush,QMutex,QThreadPool,QCoreApplication
from PyQt5 import QtCore,QtWidgets
import sys
class mylogin(QMainWindow, Ui_MainWindow1):
def __init__(self):
super(mylogin, self).__init__() # 继承父类
self.setupUi(self) # 对应Ui_MainWindow1.setupUI
if __name__ == "__main__":
app = QApplication(sys.argv)
loginUI = mylogin() # 实例化类
loginUI.show() # 展示界面
sys.exit(app.exec())
效果如下
逻辑设计
登陆按钮的对象名为pushButton
由于clicked作为一个信号,直接调用connect方法即可
self.pushButton.clicked.connect(self.login)
接下来写login方法,由于需要进入数据库查询,首先得搭建个本地数据库,关于数据库的搭建方法请跳转我的csdn文章
这里直接上建表sql过程,打开powershell,输入如下命令并输入密码链接数据库
mysql -uroot -p
CREATE DATABASE classDesign;
USE classDesign;
CREATE TABLE loginAccount
(
username CHAR(20) NOT NULL,
password CHAR(20) NOT NULL,
group1 CHAR(20) NOT NULL,
PRIMARY KEY(username)
);
至此建表完成
接下来接着写login方法
import pymysql
def login(self):
mysqlConnect = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root', # 你的用户名
passwd='', # 你的数据库密码
db='classDesign')
inPutUsername = self.lineEdit.text() # 取得现在输入的用户名
inPutPassword = self.lineEdit_2.text() # 取得现在输入的密码
cur = mysqlConnect.cursor()
if inPutUsername.strip("") == "" or inPutPassword.strip("") == "":
QMessageBox.information(None, "提示", "请输入用户名或密码", QMessageBox.Yes)
return
try:
cur.execute('SELECT * FROM loginAccount WHERE username = "{}";'.format(inPutUsername))
result = cur.fetchall() # 返回数组[username,password]形式
password = result[0][1]
if inPutPassword == password: # 如果返回的密码和输入的密码正确
QMessageBox.information(None, "提示", "登陆成功", QMessageBox.Yes)
else:
QMessageBox.information(None, "提示", "密码不正确", QMessageBox.Yes)
except Exception as e:
QMessageBox.information(None,"提示","用户名不存在",QMessageBox.Yes) # 如果sql语句找不到username就会返回错误,这里使用了try-except捕获错误
mysqlConnect.close()
同理写注册逻辑
def register(self):
mysqlConnect = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root', # 你的用户名
passwd='', # 你的数据库密码
db='classDesign')
inPutUsername = self.lineEdit_3.text() # 取得现在输入的用户名
if self.lineEdit_4.text() != self.lineEdit_5.text():
QMessageBox.information(None,"提示","两次输入的账号密码不同",QMessageBox.Yes)
inPutPassword = self.lineEdit_4.text() # 取得现在输入的密码
cur = mysqlConnect.cursor()
try:
cur.execute('INSERT INTO loginAccount (username,password)VALUES(%s,%s);',
[inPutUsername, inPutPassword])
mysqlConnect.commit()
QMessageBox.information(None, "提示", "注册成功", QMessageBox.Yes)
except Exception as e:
QMessageBox.information(None,"提示","用户名已存在",QMessageBox.Yes)
mysqlConnect.close()
运行效果如下
注册
登陆
正确情况
没输入用户名密码情况
用户名不正确情况
密码不正确情况
自动登陆和保存账号密码
使用python自带的configparser库实现保存设置
步骤无非2个,取得数据,保存到当前文件夹的.ini文件
我这里写在了mylogin类的初始化上
但是这样做会有个问题,如果初始化了,那么登陆过后,下面的show()方法依旧运行
就会变成这样
那么在这里的show()加上一个判断条件即可解决
顺便把保存做成一个接口,以后想要保存直接self.save()就可以代码复用
main完整代码
from login import Ui_MainWindow1
from PyQt5.QtWidgets import QApplication, QMainWindow,QMessageBox,QGroupBox,QHeaderView,QMenu,QAbstractItemView
from PyQt5.QtGui import QIcon,QStandardItemModel,QStandardItem,QCursor
from PyQt5.Qt import QThread, pyqtSignal,QSize,QColor,QBrush,QMutex,QThreadPool,QCoreApplication
from PyQt5 import QtCore,QtWidgets
import sys
import pymysql
class mylogin(QMainWindow, Ui_MainWindow1):
def __init__(self):
super(mylogin, self).__init__() # 继承父类
self.setupUi(self) # 对应Ui_MainWindow1.setupUI
self.pushButton.clicked.connect(self.login) # 登陆
self.pushButton_2.clicked.connect(self.close) # 退出
self.pushButton_5.clicked.connect(self.register) # 注册
self.pushButton_4.clicked.connect(self.close) # 退出
def login(self):
mysqlConnect = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root', # 你的用户名
passwd='', # 你的数据库密码
db='classDesign')
inPutUsername = self.lineEdit.text() # 取得现在输入的用户名
inPutPassword = self.lineEdit_2.text() # 取得现在输入的密码
cur = mysqlConnect.cursor()
if inPutUsername.strip("") == "" or inPutPassword.strip("") == "":
QMessageBox.information(None, "提示", "请输入用户名或密码", QMessageBox.Yes)
return
try:
cur.execute('SELECT * FROM loginAccount WHERE username = "{}";'.format(inPutUsername))
result = cur.fetchall() # 返回数组[username,password]形式
password = result[0][1]
if inPutPassword == password: # 如果返回的密码和输入的密码正确
QMessageBox.information(None, "提示", "登陆成功", QMessageBox.Yes)
else:
QMessageBox.information(None, "提示", "密码不正确", QMessageBox.Yes)
except Exception as e:
QMessageBox.information(None,"提示","用户名不存在",QMessageBox.Yes) # 如果sql语句找不到username就会返回错误,这里使用了try-except捕获错误
mysqlConnect.close()
def register(self):
mysqlConnect = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root', # 你的用户名
passwd='', # 你的数据库密码
db='classDesign')
inPutUsername = self.lineEdit_3.text() # 取得现在输入的用户名
if self.lineEdit_4.text() != self.lineEdit_5.text():
QMessageBox.information(None,"提示","两次输入的账号密码不同",QMessageBox.Yes)
inPutPassword = self.lineEdit_4.text() # 取得现在输入的密码
cur = mysqlConnect.cursor()
try:
cur.execute('INSERT INTO loginAccount (username,password)VALUES(%s,%s);',
[inPutUsername, inPutPassword])
mysqlConnect.commit()
QMessageBox.information(None, "提示", "注册成功", QMessageBox.Yes)
except Exception as e:
QMessageBox.information(None,"提示","用户名已存在",QMessageBox.Yes)
mysqlConnect.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
loginUI = mylogin() # 实例化类
loginUI.show() # 展示界面
sys.exit(app.exec())
主程序模块
实现用户权限管理
我的思路是通过新增一个表,并且在loginAccount中新增权限(group)字段,通过连接表实现权限,这是受到linux读写权限启发得来
添加权限表
表设计如下
group | add | delete | update | select | editAccount |
---|---|---|---|---|---|
admin | 1 | 1 | 1 | 1 | 1 |
user | 0 | 0 | 0 | 1 | 0 |
admin权限组可以实现增删改查,user权限组只能修改自己的密码(默认权限,这里省略字段了),查询表
制作ui
创建一个新窗口
ctrl+s保存为myMainWindow.ui
添加tab widget,方便其他功能使用
使用栅格布局,改变ui的观感
改变tab1的名字,改为用户管理
以下略
我设计ui的水瓶一般,随便看看就好
查询按钮实现
好懒不想写细节了,大概思路就是添加一个tableView,然后请求数据库返回的信息处理后,往tableView写数据,我这里直接在表格右键实现了添加修改删除三个功能
主要说一下遇到的麻烦
添加
主要解决添加以后直接显示添加出来数据
由于提前把刷新数据做了一个方法接口,直接在插入数据以后调用即可
修改
修改密码倒是简单,主要解决修改用户名
用户名修改的时候有两个问题
- 用户名是主键,如果修改容易出事情
- 用户名右键修改的时候,没法获取原来的用户名
问题1我选择了删除主键,修改,然后再增加主键的做法,以前是先把这一条数据保存起来,再删除,再添加回去新修改的数据
问题2,由于我选择了删除主键,修改,没有保存原来的数据,在这里耗费了很多时间。
我在mainUI.setData()方法里添加了一个self.data用于保存原先的数据
于是问题迎刃而解了
删除
由于删除会直接改变表格的数据条数,删除以后会导致表格存在重复项没有消去
我的解决方法是直接保存当前行所在的序号,然后删除后直接调用removeRow(index),直接删掉对应行
修改密码按钮实现
我直接对着改密按钮clicked信号链接到一个创建新ui,并且调用新ui的方法实现相应逻辑
问题在于修改密码以后自动登录会乱掉。比如如果密码错误,之前已经删除掉了show()方法,登陆按钮在弹出密码错误的框以后不会显示。
在login添加一个自动登陆的flag,实现相应的逻辑
车辆信息
由于接下来要实现的功能和上面高度相似,需要注意的问题是复用表,其他的我觉得没有必要再写了,添加个标题看起来整齐点
建表sql语句
CREATE TABLE carProfile(
type char(10),
brand char(2),
engineNo char(10),
carNo char(8),
Num char(6),
PRIMARY KEY(Num)
)
主要是实现单独查询的功能,我这里给右键菜单添加了一个独特查询按键
点进去是这样的
如果要查询桂A23348这个车辆,那么就在这里找到他的车牌然后点击查询,会打开一个新表
驾驶员信息
同上一模一样的功能,也是右键查询
CREATE TABLE driverProfile(
name char(12),
IDcard char(18),
address char(30),
contact char(11),
code char(6),
driverNo char(8),
PRIMARY KEY(driverNo)
)
投诉信息
CREATE TABLE issue(
carNo char(10),
reason char(50),
time datetime(0) NOT NULL DEFAULT now(),
opinion char(50),
operator char(12),
Num char(8),
PRIMARY KEY(Num)
)
这里比较重要的是实现的车辆信息必须先查询,把sql语句改一下就行了
这样就能查询对应的车辆是否存在违规信息
字段约束
我考虑的是在添加,修改的时候额外添加一个窗口,和之前的用表格修改区别开来
吃饭先