- 花一上午帮同学写的期末作业
- 大概写下流程记录下
Begin
GUI设计
使用Qt Designer完成 .ui
文件
生成py文件 pyuic5 -o xx.py xx.ui
代码
管理端
from PyQt5 import QtCore, QtGui, QtSql, QtWidgets
import sys
import sqlite3
import os
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
from PyQt5.QtWidgets import QApplication, QWidget
# 管理界面GUI
class manageUI(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(1000, 400)
Form.setFixedSize(Form.width(), Form.height())
self.tableView = QtWidgets.QTableView(Form)
self.tableView.setGeometry(QtCore.QRect(10, 10, 981, 291))
self.tableView.setObjectName("tableView")
self.gridLayoutWidget = QtWidgets.QWidget(Form)
self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 310, 481, 80))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.pushButton = QtWidgets.QPushButton(self.gridLayoutWidget)
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
self.pushButton_2 = QtWidgets.QPushButton(self.gridLayoutWidget)
self.pushButton_2.setObjectName("pushButton_2")
self.gridLayout.addWidget(self.pushButton_2, 1, 0, 1, 1)
self.gridLayoutWidget_2 = QtWidgets.QWidget(Form)
self.gridLayoutWidget_2.setGeometry(QtCore.QRect(510, 310, 481, 80))
self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setObjectName("gridLayout_2")
self.pushButton_3 = QtWidgets.QPushButton(self.gridLayoutWidget_2)
self.pushButton_3.setObjectName("pushButton_3")
self.gridLayout_2.addWidget(self.pushButton_3, 0, 0, 1, 1)
self.pushButton_4 = QtWidgets.QPushButton(self.gridLayoutWidget_2)
self.pushButton_4.setObjectName("pushButton_4")
self.gridLayout_2.addWidget(self.pushButton_4, 1, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "隔离人员管理"))
self.pushButton.setText(_translate("Form", "刷新数据"))
self.pushButton_2.setText(_translate("Form", "删除人员"))
self.pushButton_3.setText(_translate("Form", "新增人员"))
self.pushButton_4.setText(_translate("Form", "退出"))
# 绑定按钮事件
# 查询
self.pushButton.clicked.connect(self.queryAll)
# 删除
self.pushButton_2.clicked.connect(self.delRow)
# 新增
self.pushButton_3.clicked.connect(self.addRow)
# 退出程序
self.pushButton_4.clicked.connect(
QtCore.QCoreApplication.instance().quit)
# 创建数据库
def createDB(self):
if os.path.exists("managePerson.db") == False:
try:
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("managePerson.db")
db.open()
c = QtSql.QSqlQuery()
c.exec('''
CREATE TABLE managePerson(
id INT PRIMARY KEY NOT NULL,
name TEXT,
age INT,
address TEXT,
begindate DATE,
day INT
);''')
# 插入测试数据
c.exec_(
"INSERT INTO managePerson VALUES (20, '张三', 18, '火星', '2020-05-08', 999);")
c.exec_(
"INSERT INTO managePerson VALUES (40, '李四', 19, '天王星', '2020-05-09', 10);")
c.exec_(
"INSERT INTO managePerson VALUES (30, '王五', 22, '海王星', '2020-02-02', 999);")
db.close()
print("创建数据库成功!")
except Exception as e:
print(e)
else:
print("数据库已存在!")
# 查询所有人员
def queryAll(self):
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("managePerson.db")
self.model = QSqlTableModel()
self.tableView.setModel(self.model)
self.model.setTable("managePerson")
self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.model.select()
self.model.setHeaderData(0, QtCore.Qt.Horizontal, '身份证号')
self.model.setHeaderData(1, QtCore.Qt.Horizontal, '姓名')
self.model.setHeaderData(2, QtCore.Qt.Horizontal, '年龄')
self.model.setHeaderData(3, QtCore.Qt.Horizontal, '地址')
self.model.setHeaderData(4, QtCore.Qt.Horizontal, '开始隔离时间')
self.model.setHeaderData(5, QtCore.Qt.Horizontal, '需要隔离天数')
# 删除用户
def delRow(self):
if self.model:
try:
self.model.removeRow(self.tableView.currentIndex().row())
except Exception as e:
print(e)
else:
self.createDB()
# 新增用户
def addRow(self):
if self.model:
try:
self.model.insertRows(self.model.rowCount(), 1)
except Exception as e:
print(e)
else:
self.createDB()
# 程序入口
if __name__ == "__main__":
app = QApplication(sys.argv)
form = QWidget()
ui = manageUI()
ui.setupUi(form)
ui.createDB()
form.show()
ui.queryAll()
sys.exit(app.exec())
查询端
from PyQt5 import QtCore, QtGui, QtSql, QtWidgets
import sys
import datetime
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
from PyQt5.QtWidgets import QMessageBox
# 查询界面GUI
class queryUI(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(800, 500)
Form.setFixedSize(Form.width(), Form.height())
self.textEdit = QtWidgets.QTextEdit(Form)
self.textEdit.setGeometry(QtCore.QRect(10, 80, 781, 341))
self.textEdit.setObjectName("textEdit")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(10, 10, 781, 61))
font = QtGui.QFont()
font.setFamily(".Heiti GB18030PUA")
font.setPointSize(22)
self.label.setFont(font)
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(10, 430, 781, 61))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "隔离剩余天数查询"))
self.textEdit.setHtml(_translate("Form", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.label.setText(_translate("Form", "身份证号:"))
self.pushButton.setText(_translate("Form", "查询剩余隔离天数"))
self.pushButton.clicked.connect(self.queryLaveDays)
# 查询剩余天数
def queryLaveDays(self):
# 获取文本框值
personNo = self.textEdit.toPlainText()
# 连接数据库
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("managePerson.db")
db.open()
c = QtSql.QSqlQuery()
c.exec("SELECT name, begindate, day FROM managePerson WHERE id=" + personNo + ";")
name = "null"
while c.next():
name = c.value(0)
begindate = c.value(1)
day = c.value(2)
print(name, begindate, day)
db.close()
# 当前日期
today = datetime.date.today()
today = datetime.datetime.strptime(str(today), "%Y-%m-%d")
try:
# 隔离开始时间
begindate = datetime.datetime.strptime(begindate, "%Y-%m-%d")
# 隔离结束时间
endDate = begindate + datetime.timedelta(days=day)
except Exception as e:
print(e)
if name == "null":
msg = "请正确输入身份证号!"
elif endDate > today:
laveDay = endDate - today
msg = name + "您好,您的隔离结束时间为" + str(endDate).replace(" 00:00:00", "") + "剩余" + str(
laveDay).replace(" days, 0:00:00", "") + "天,请耐心等待!"
else:
msg = name + "您好,您已结束隔离期!"
QMessageBox().information(None, "隔离剩余天数查询", msg, QMessageBox.Yes)
# 程序入口
if __name__ == "__main__":
app = QApplication(sys.argv)
form = QWidget()
ui = queryUI()
ui.setupUi(form)
form.show()
sys.exit(app.exec())
打包为exe
pip install pyinstaller
使用PyInstaller
pyinstaller的语法:pyinstaller [options] script [script...] | specfile
最简单的用法,在和myscript.py同目录下执行命令:pyinstaller mycript.py
然后会看到新增加了两个目录build和dist,dist下面的文件就是可以发布的可执行文件,对于上面的命令你会发现dist目录下面有一堆文件,各种都动态库文件和myscrip可执行文件。有时这样感觉比较麻烦,需要打包dist下面的所有东西才能发布,万一丢掉一个动态库就无法运行了,好在pyInstaller支持单文件模式,只需要执行:
pyinstaller -F mycript.py
你会发现dist下面只有一个可执行文件,这个单文件就可以发布了,可以运行在你正在使用的操作系统类似的系统的下面。当然,pyinstaller还有各种选项,有通用选项,如-d选项用于debug。
在执行pyInstaller命令的时候,会在和脚本相同目录下,生成一个.spec文件,该文件会告诉pyinstaller如何处理你的所有脚本,同时包含了命令选项。一般我们不用去理会这个文件,若需要打包数据文件,或者给打包的二进制增加一些Python的运行时选项时...一些高级打包选项时,需要手动编辑.spec文件。可以使用:pyi-makespec optionsscript [script ...]
创建一个.spec文件,对于手动编辑的.spec文件,我们可以使用下面任意一条命令:pyinstaller specfile
pyi-build specfile
PyInstaller原理简介
PyInstaller其实就是把python解析器和你自己的脚本打包成一个可执行的文件,和编译成真正的机器码完全是两回事,所以千万不要指望成打包成一个可执行文件会提高运行效率,相反可能会降低运行效率,好处就是在运行者的机器上不用安装python和你的脚本依赖的库。在Linux操作系统下,它主要用的binutil工具包里面的ldd和objdump命令。
PyInstaller输入你指定的的脚本,首先分析脚本所依赖的其他脚本,然后去查找,复制,把所有相关的脚本收集起来,包括Python解析器,然后把这些文件放在一个目录下,或者打包进一个可执行文件里面。
可以直接发布输出的整个文件夹里面的文件,或者生成的可执行文件。你只需要告诉用户,你的应用App是自我包含的,不需要安装其他包,或某个版本的Python,就可以直接运行了。
需要注意的是,PyInstaller打包的执行文件,只能在和打包机器系统同样的环境下。也就是说,不具备可移植性,若需要在不同系统上运行,就必须针对该平台进行打包。
实践问题
- pyinstaller打包后的exe运行怎么去掉弹出的命令行提示窗口?
1.如果使用.spec文件的话, 在该文件中找到console=True修改为console=False
2.如果是直接指定python文件进行pyinstaller打包的话,需要添加—noconsole
pyinstaller path\\mycode.py--noconsole
如果想只打包成一个exe:
pyinstaller -F path\\mycode.py --noconsole
或:
pyinstaller -F -wpath\\mycode.py
- 更换最终exe生成路径
在cmd中,一开始就要 cd D:\PythonEXE\ 切换到输出文件夹,然后在用上面的代码,说明:各个参数的作用,
例子:pyinstaller -F -w -pD:\tmp\core-python\libs -i d:\tmp\main.ico main.py
-F 表示生成单个可执行文件;
-D –onedir 创建一个目录,包含exe文件,但会依赖很多文件(默认选项)。
-w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!;
-c –console, –nowindowed 使用控制台,无界面(默认);
-p 表示你自己自定义需要加载的类路径,一般情况下用不到;
-i 表示可执行文件的图标。
参考链接:
- https://blog.csdn.net/zengxiantao1994/article/details/76578421
- https://www.codercto.com/a/19041.html?tdsourcetag=s_pctim_aiomsg
版权属于:moluuser
本文链接:https://archive.moluuser.com/archives/51/
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。