界面展示
1、安装wxPython
pip install -U wxPython
2、安装pymysql
pip install PyMySQL
3、安装pyinstaller,打包exe文件需要用到
pip install pyinstaller
4、完整代码
wxPython 部分代码参考(https://blog.csdn.net/zha6476003/article/details/82938015)
#!/usr/bin/python
import wx
import time
import pymysql
import hashlib
count = 0 #登录次数统计
is_login = 0 #登录标识
def md5(str):
m = hashlib.md5()
m.update(str.encode("utf8"))
return m.hexdigest()
def md5GBK(str1):
m = hashlib.md5(str1.encode(encoding='gb2312'))
print(m.hexdigest())
return m.hexdigest()
#定义数据库查询方法
def mysql(sql,type):
try:
# 打开数据库连接
db = pymysql.connect("数据库地址", "数据库账号", "数据库密码", "数据库名称")
except:
print('数据库连接失败,10s后重试')
time.sleep(10)
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
results = ()
try:
# 使用 execute() 方法执行 SQL 查询
cursor.execute(sql)
if type == 'fetchall':
results = cursor.fetchall()
if type == 'fetchone':
# 使用 fetchone() 方法获取单条数据.
results = cursor.fetchone()
except:
print("Error: unable to fetch data")
# 关闭数据库连接
db.close()
return results
#登录界面
class Login(wx.Frame):
def __init__(self, parent, id, count, is_login):
self.count = count
self.is_login = is_login
if self.is_login:
app = wx.App() # 初始化
frame_home = Home(parent=None, id=-1, is_login=1) # 实例MyFrame类,并传递参数
frame_home.Show() # 显示窗口
app.MainLoop() # 调用主循环方法
else:
wx.Frame.__init__(self, parent, id, '用户登录', size=(400, 300))
# 创建面板
panel = wx.Panel(self)
# 创建“确定”和“取消”按钮, 并绑定事件
self.bt_confirm = wx.Button(panel, label='确定')
self.bt_confirm.Bind(wx.EVT_BUTTON, self.OnclickSubmit)
self.bt_cancel = wx.Button(panel, label='取消')
self.bt_cancel.Bind(wx.EVT_BUTTON, self.OnclickCancel)
# 创建文本,左对齐
self.title = wx.StaticText(panel, label="请输入用户名和密码")
self.label_user = wx.StaticText(panel, label="用户名:")
self.text_user = wx.TextCtrl(panel, style=wx.TE_LEFT)
self.label_pwd = wx.StaticText(panel, label="密 码:")
self.text_password = wx.TextCtrl(panel, style=wx.TE_PASSWORD)
# 添加容器,容器中控件按横向并排排列
hsizer_user = wx.BoxSizer(wx.HORIZONTAL)
hsizer_user.Add(self.label_user, proportion=0, flag=wx.ALL, border=5)
hsizer_user.Add(self.text_user, proportion=1, flag=wx.ALL, border=5)
hsizer_pwd = wx.BoxSizer(wx.HORIZONTAL)
hsizer_pwd.Add(self.label_pwd, proportion=0, flag=wx.ALL, border=5)
hsizer_pwd.Add(self.text_password, proportion=1, flag=wx.ALL, border=5)
hsizer_button = wx.BoxSizer(wx.HORIZONTAL)
hsizer_button.Add(self.bt_confirm, proportion=0, flag=wx.ALIGN_CENTER, border=5)
hsizer_button.Add(self.bt_cancel, proportion=0, flag=wx.ALIGN_CENTER, border=5)
# 添加容器,容器中控件按纵向并排排列
vsizer_all = wx.BoxSizer(wx.VERTICAL)
vsizer_all.Add(self.title, proportion=0, flag=wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER, border=15)
vsizer_all.Add(hsizer_user, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=45)
vsizer_all.Add(hsizer_pwd, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=45)
vsizer_all.Add(hsizer_button, proportion=0, flag=wx.ALIGN_CENTER | wx.TOP, border=15)
panel.SetSizer(vsizer_all)
def OnclickSubmit(self, event):
""" 点击确定按钮,执行方法 """
message = ""
username = self.text_user.GetValue() # 获取输入的用户名
password = self.text_password.GetValue() # 获取输入的密码
if self.count == 3:
message = '错误超过%d次,你已经没有机会了' % self.count
else:
if username == "" or password == "": # 判断用户名或密码是否为空
message = '用户名或密码不能为空,还有%d次机会' % (2 - self.count)
self.count += 1
else:
#根据用户查询出加密字符串
sql = "select salt from admin where username = '%s'" % (username)
admin_salt = mysql(sql, 'fetchone')
if admin_salt != None and admin_salt != "":
#根据用户密码匹配用户数据
sql = "select id,username,language_id from admin where username = '%s' and password = '%s'" % (username, md5(password + admin_salt[0]))
results = mysql(sql, 'fetchone')
if results != None and results != "":
message = '登录成功,用户名:' + results[1]
self.is_login = 1
else:
message = '用户名或密码错误,还有%d次机会' % (2 - self.count)
self.count += 1
else:
message = '用户名或密码错误,还有%d次机会' % (2 - self.count) # 用户名或密码错误
self.count += 1
wx.MessageBox(message) # 弹出提示框
if self.is_login:
frame.Destroy() #关闭窗口
app = wx.App() # 初始化
frame_home = Home(parent=None, id=-1, is_login=1, results=results) # 实例MyFrame类,并传递参数
frame_home.Show() # 显示窗口
app.MainLoop() # 调用主循环方法
def OnclickCancel(self, event): # 没有event点击取消会报错
""" 点击取消按钮,执行方法 """
self.text_user.SetValue("") # 清空输入的用户名
self.text_password.SetValue("") # 清空输入的密码
#管理中心首页
class Home(wx.Frame):
def __init__(self, parent, id, is_login, results):
if is_login:
wx.Frame.__init__(self, parent, id, '管理中心', size=(1600, 970))
# 创建面板
panel = wx.Panel(self)
language_id = results[2]
if results[2] == 0:
language_id = 42
sql = "select name,code from language where language_id = %d" % language_id
languageInfo = mysql(sql, 'fetchone')
if languageInfo != None and languageInfo != "":
# 创建文本,左对齐
self.title = wx.StaticText(panel, label="你好:"+results[1]+" 欢迎登录后台管理系统, 当前语种:"+languageInfo[0]+", 语种代码:"+languageInfo[1])
# 添加容器,容器中控件按纵向并排排列
vsizer_all = wx.BoxSizer(wx.VERTICAL)
vsizer_all.Add(self.title, proportion=0, flag=wx.BOTTOM | wx.TOP | wx.ALIGN_CENTER, border=15)
panel.SetSizer(vsizer_all)
else:
app = wx.App() # 初始化
frame = Login(parent=None, id=-1, count=0, is_login=1) # 实例MyFrame类,并传递参数
frame.Show() # 显示窗口
app.MainLoop() # 调用主循环方法
if __name__ == '__main__':
app = wx.App() # 初始化
frame = Login(parent=None, id=-1, count=0, is_login=0) # 实例MyFrame类,并传递参数
frame.Show() # 显示窗口
app.MainLoop() # 调用主循环方法
5、把python文件打包成exe文件 加上-w小写可以屏蔽黑窗口
在py程序所在文件夹,打开cmd,输入pyinstaller -F login.py,打包为一个可运行程序。
pyinstaller -D -w -i "D:\wwwroot\python\login\favicon.ico" ****.py
如运行后报错:struct.error: unpack requires a buffer of 16 bytes
ico图标在线转换一下就可以了:http://www.ico51.cn/
pyinstaller相关参数
-F:生成一个文件夹,里面是多文件模式,启动快。
-D:仅仅生成一个文件,不暴露其他信息,启动较慢。
-w:窗口模式打包,不显示控制台。
-i:跟图标路径,作为应用icon。