当前位置:   article > 正文

山东大学数据库实验三——模拟铁路售票系统

山东大学数据库实验三——模拟铁路售票系统

README

本文为记录开发山东大学计算机学院数据库实验三——数据库应用开发的过程,我们小组选择了模拟铁路售票系统这个选题,这个选题算是一个比较简单的题目了,记录一下开发过程,希望能对大家有所启发

概览

该程序主要使用Python开发,应用了pyMySQL连接MySQL数据库,使用pyQt5实现可视化界面

该程序还应用了连接阿里云RDS for MySQL,实现了云端服务、脱机使用,在任意一台Windows主机上都可以运行

该程序主要面向两个用户——普通用户、管理员,两个用户的功能不相同

普通用户功能主要有:购票、退票、账户车票查询、账户管理

管理员功能主要有:管理用户(删除用户、修改用户密码)、管理车次(增加、删除车次)、更新车次信息

页面创建流程

每个页面由page_name.ui、page_name.py、page_name_pre.py三个文件组成

首先适用Pycharm插件qtdesigner设计出页面的大体框架,设计好信号以及槽函数并连接

qtdesigner不建议关闭,如果后续要修改界面相关组成或者信号槽,可以直接在里面编辑

设计完界面之后,保存到项目根目录,在Pycharm中选中该.ui文件,使用外部工具PyUIC生成该页面的.py文件,但是此时该文件并不能直接运行、显示或者被其他界面调用,需要通过驱动程序驱动显示

这时就要创建一个pre.py文件,这里面包含对槽函数、信号的定义、对界面的代码更改以及一些其他格式定义,这里以登录界面login_pre.py为例,讲解驱动程序的结构

该文件所用到的模块一般有:

  1. import sys
  2. from PyQt5.QtGui import QPixmap,QPalette,QFont,QGuiApplication # PyQt相关模块
  3. from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
  4. from PyQt5.QtCore import *
  5. from login import Ui_tratic # 这是login界面的驱动程序,若是其他界面,换成界面名字即可

接着连接数据库,这里我使用了阿里云RDS,大家可以使用自己本地的MySQL账户和密码登录

  1. import pymysql
  2. db=pymysql.connect(host="xxxx.mysql.rds.aliyuncs.com",user="alphonza",password="QAZwsx123",database="tratic")
  3. cursor=db.cursor() # 定义游标,后续通过游标访问数据库信息

这里还用到了一个函数,这个函数用以在程序打包的时候,找到图片等资源文件的路径,以使我们可以在代码中访问这些文件,在打包时,将源文件添加到目录中即可:

  1. import os
  2. def get_path(relative_path):
  3. try:
  4. base_path = sys._MEIPASS
  5. except AttributeError:
  6. base_path = os.path.abspath(".")
  7. return os.path.normpath(os.path.join(base_path, relative_path))

 定义界面类,以及构造函数:

  1. class MyMainWindow(QMainWindow, Ui_tratic): # 继承 QMainWindow类和 Ui_tratic界面类
  2. # 信号定义在这里
  3. signal_phone=pyqtSignal(str) # 传给主界面账号、密码等信息
  4. signal_password=pyqtSignal(str)
  5. signal_left=pyqtSignal(str) # 激发显示欢迎语句的信号
  6. def __init__(self, parent=None):
  7. super(MyMainWindow, self).__init__(parent) # 初始化父类
  8. self.setupUi(self) # 继承 Ui_MainWindow 界面类
  9. self.setWindowTitle("login")# 设置标题

之后可以继续在构造函数中编写其他内容,这些代码是在构建这个界面时就会运行的,比如我的login界面的构造函数里还有:

  1. pix = QPixmap(get_path("assets/铁路.png"))# 导入图片(调用get_path函数)
  2. self.label_3.setPixmap(pix)
  3. self.label_3.setScaledContents(True)
  4. pix1 = QPixmap(get_path("assets/背景.jpg")) # 导入图片
  5. self.label_4.setPixmap(pix1)
  6. self.label_4.setScaledContents(True)
  7. font = QFont("黑体", 24, 75)
  8. pe = QPalette()
  9. pe.setColor(QPalette.WindowText, Qt.black) # 设置字体样式
  10. self.label_2.setFont(font)
  11. self.label_5.setFont(font)
  12. self.label.setFont(font)
  13. self.label_2.setPalette(pe)
  14. self.label.setPalette(pe)
  15. self.label_5.setPalette(pe)

类定义中还要包含界面设计的所有槽函数的定义,以下是login_fun定义:

  1. def login_fun(self):
  2. '''登录槽函数'''
  3. phone=self.lineEdit.text() # 获取用户输入
  4. password=self.lineEdit_2.text()
  5. # 定义sql语句,sql语句全部用字符串变量描述,后续传给游标
  6. login_sql = "select keyword from passenger where(phone_number='{}')".format(phone)
  7. cursor.execute(login_sql)
  8. password_database = cursor.fetchone()
  9. if password_database==None: # 用户不存在或者是管理员账户
  10. admin_login_sql="select password from admin where(admin_id='{}')".format(phone)
  11. cursor.execute(admin_login_sql)
  12. admin_password_database=cursor.fetchone()
  13. if admin_password_database==None:
  14. QMessageBox.information(self, "提示", """用户不存在!""")
  15. return
  16. if password==admin_password_database[0]: # 是管理员账户
  17. QMessageBox.information(self, "提示", """登录成功!""")
  18. import admin_main_interface_pre # 链接另一个界面,admin_main_interface界面
  19. self.four = admin_main_interface_pre.MyMainWindow() # 用一个变量保存被调用界面的主类
  20. # 传递信号给被调用界面
  21. self.signal_phone.connect(self.four.aget_phone)
  22. self.signal_phone.emit(phone)
  23. self.signal_password.connect(self.four.aget_password)
  24. self.signal_password.emit(password)
  25. self.signal_left.connect(self.four.astart_left)
  26. self.signal_left.emit("start")
  27. self.four.show() # 像用户展示被调用界面,有时还需要关闭调用界面
  28. else:
  29. QMessageBox.information(self, "提示", """用户不存在!""")
  30. if password==admin_password_database[0]:
  31. self.close()
  32. self.lineEdit_2.clear()
  33. return
  34. if password == password_database[0]: # 登录成功,进入主界面
  35. QMessageBox.information(self, "提示", """登录成功!""")
  36. import main_interface_pre
  37. self.two=main_interface_pre.MyMainWindow()
  38. self.signal_phone.connect(self.two.get_phone)
  39. self.signal_phone.emit(phone)
  40. self.signal_password.connect(self.two.get_password)
  41. self.signal_password.emit(password)
  42. self.signal_left.connect(self.two.start_left)
  43. self.signal_left.emit("start")
  44. self.two.show()
  45. self.close()
  46. else: # 密码错误
  47. QMessageBox.warning(self, "提示","""密码错误,请重新输入!""")
  48. self.lineEdit_2.clear()
  49. return

以下是创建普通账户、管理员账户的槽函数:

  1. def create_account(self):
  2. '''创建账户槽函数'''
  3. import create_account_pre # 链接create_account界面
  4. self.one=create_account_pre.MyMainWindow()
  5. self.one.show()
  6. self.close() #关闭当前界面
  7. def admin_create_account(self):
  8. '''创建管理员账户槽函数'''
  9. import admin_create_account_pre
  10. self.three=admin_create_account_pre.MyMainWindow()
  11. self.three.show()
  12. self.close()

还要在结尾处包含以下代码:

  1. # 设置界面适应系统缩放比例
  2. QGuiApplication.setAttribute(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
  3. QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
  4. QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
  5. QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
  6. if __name__ == '__main__':
  7. app = QApplication(sys.argv) # 在 QApplication 方法中使用,创建应用程序对象
  8. myWin = MyMainWindow() # 实例化 MyMainWindow 类,创建主窗口
  9. myWin.show() # 在桌面显示控件 myWin
  10. sys.exit(app.exec_()) # 结束进程,退出程序

login界面效果

其他界面的驱动函数编写流程大同小异,根据所需要的功能,编写相应的槽函数实现

其他问题

Q:如何配置两个外部工具?

A:设置里点击外部工具——添加——输入相应指令

qtdesigner配置

pyuic配置


Q:如何使用qtdesigner?

A:可以参照[ PyQt入门教程 ] Qt Designer工具的使用_qtdesigner教程-CSDN博客


Q:如何打包?

A:在根目录中添加内容如下的.spec文件

  1. # -*- mode: python ; coding: utf-8 -*-
  2. a = Analysis( # 这里填写你目录中所有的.py文件
  3. ['login_pre.py','login.py','create_account.py','create_account_pre.py','main_interface.py','main_interface_pre.py','query.py','query_pre.py','query_result.py','query_result_pre.py','show_result.py','show_result_pre.py','tickets_hold.py','tickets_hold_pre.py','add_trains.py','add_trains_pre.py','admin_create_account.py','admin_create_account_pre.py','admin_main_interface.py','admin_main_interface_pre.py','manage_passenger.py','manage_passenger_pre.py','manage_train.py','manage_train_pre.py','change_password.py','change_password_pre.py','change_password_pa.py','change_password_pa_pre.py'],
  4. pathex=[],
  5. binaries=[],
  6. datas=[('assets','assets')], # 这里填写你的资源存放的文件夹名字
  7. hiddenimports=[],
  8. hookspath=[],
  9. hooksconfig={},
  10. runtime_hooks=[],
  11. excludes=[],
  12. noarchive=False,
  13. )
  14. pyz = PYZ(a.pure)
  15. exe = EXE(
  16. pyz,
  17. a.scripts,
  18. a.binaries,
  19. a.datas,
  20. [],
  21. name='tratic', # 这里填写你的程序名字
  22. debug=False,
  23. bootloader_ignore_signals=False,
  24. strip=False,
  25. upx=True,
  26. upx_exclude=[],
  27. runtime_tmpdir=None,
  28. console=False,
  29. disable_windowed_traceback=False,
  30. argv_emulation=False,
  31. target_arch=None,
  32. codesign_identity=None,
  33. entitlements_file=None,
  34. )

然后在pycharm控制台,cd到根目录,运行如下指令,即可打包完成

pyinstaller xxx.spec

有关qt相关问题可以自行查找书籍资料或者其他博文

LAST

有什么问题可以评论区问喔

这里贴一下我的源码地址

tratic: tratic模拟铁路购票系统

希望能帮到大家!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号