前几天我用 Pyinstaller打包Tkinter创建的GUI应用程序之后,考虑到软件如果被传播导致滥用,不如添加一个账号登陆功能,这样能够有效限制使用者。本文将之前做好的GUI远程连接MySQL数据库,实现远程账户登陆。
1 搭建MySQL环境
1.1 MySQL下载及安装
1.2 远程MySQL数据库配置
2.登陆界面
2.1 Python Tkinter写登陆界面的UI
2.2 完整代码:
3 参考资料:
官网下载mysql-8.0.11-winx64.zip,解压至D盘根目录。管理员运行Windows Powershell,逐条执行如下命令:
cd D:\mysql\bin
.\mysqld --install
.\mysqld --initialize --user=root --console
net start mysql
.\mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY '修改密码';
FLUSH PRIVILEGES;
执行第三条命令后,会初始化MySQL数据库,并打印出MySQL默认生成的密码,复制此条密码;
执行第五条命令后,登陆MySQL,输入复制的密码,进入数据库;
第六条命令为修改默认密码,汉字更改为想要设置的密码。
这样MySQL就在本地安装好并启动服务了。
我想将创建MySQL数据库的电脑作为服务器,使得我可以在其他电脑远程访问并登陆。在该电脑上按上述创建好MySQL之后,还需要开启MySQL远程访问权限,此外我使用的MySQL服务器电脑处于局域网中,需要进行端口映射,并获知外网IP。具体如下:
1. 登陆MySQL数据库,查看user表,通过update这条命令将host字段的值改为%,表示在任何客户端机器上能以root用户登录到mysql服务器。
mysql> use mysql
Database changed
mysql> update user set host = '%' where user = 'root';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
mysql> select host, user from user;
+-----------+------------------+
| host | user |
+-----------+------------------+
| % | root |
| localhost | mysql.infoschema |
| localhost | mysql.session |
| localhost | mysql.sys |
+-----------+------------------+
4 rows in set (0.00 sec)
mysql>FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
2. MySQL服务器电脑防火墙中开启3306端口,入站规则中新建允许端口为3306,命名为mysql即可。然后在路由器配置中将IP-MAC绑定,执行端口映射。此时可尝试用别的电脑(需安装MySQL,或有Navicat)访问该数据库,访问IP须为路由器外网IP。命令为:
.\mysql -h 外网IP地址 -P 3306 -u root -p
Navicat从官网下载即可,破解补丁下载链接(密码: 2icj)。
新建连接-MySQL,输入主机即为服务器外网IP地址,输入用户名和密码,连接。
新建数据库,命名为userbase,表栏目下新建表,命名为userlist,并添加两列:
首先pip命令安装pymysql(python3)。UI界面见图。
点击确定之后出现下图(之前制作的UI)
实现功能:用户打开软件后,输入账号密码,访问远程数据库中userlist,验证符合之后,登陆成功,跳转至正式软件。
# coding=gbk
import pymysql
from dealUI import * # 之前写的穿越火线交易所辅助
import base64
from icon import img
from os import remove
class Login(object):
def __init__(self):
self.root = Tk()
self.root.title('登录')
self.root.resizable(0, 0)
sw = self.root.winfo_screenwidth()
sh = self.root.winfo_screenheight()
x = (sw - 300) / 2
y = (sh - 200) / 2
self.root.geometry('%dx%d+%d+%d' % (285, 180, x, y))
self.lb_user = ttk.Label(self.root, text='用户名:')
self.lb_passwd = ttk.Label(self.root, text='密码:')
self.lb_user.grid(row=0, column=0, sticky=W, padx=30, pady=28)
self.lb_passwd.grid(row=2, column=0, sticky=W, padx=30)
self.en_user = ttk.Entry(self.root)
self.en_user.focus()
self.en_passwd = ttk.Entry(self.root, show='*')
self.en_user.grid(row=0, column=1, columnspan=1)
self.en_passwd.grid(row=2, column=1, columnspan=1)
self.en_user.insert(0, '')
self.en_passwd.insert(0, '')
self.var = IntVar()
style = ttk.Style()
style.map("C.TButton",
foreground=[('pressed', '#FE4C40'), ('active', '#F76F60')],
background=[('pressed', '!disabled', '#ACE1AF'), ('active', '#fedcbd')]
)
self.On_help = ttk.Button(self.root, text="注册", command=onHelp, style="C.TButton")
self.On_help.grid(row=3, column=0, sticky=E)
self.On_login = ttk.Button(self.root, text='登陆', style="C.TButton")
self.On_login.grid(row=3, column=1, sticky=E, pady=30)
self.On_login.config(command=self.login)
tmp = open("tmp.ico", "wb+")
tmp.write(base64.b64decode(img))
tmp.close()
self.root.iconbitmap('tmp.ico') # 加图标
remove("tmp.ico") # 删掉临时文件
self.root.mainloop()
def login(self):
en1_value = self.en_user.get().strip()
en2_value = self.en_passwd.get().strip()
txt = '''用户名: %s \n密码 : %s ''' % (self.en_user.get(), self.en_passwd.get())
if en1_value == '' or en1_value == '输入用户名':
messagebox.showwarning('无用户名', '请输入用户名')
elif en2_value == '' or en2_value == '输入密码':
messagebox.showwarning('无密码', '请输入密码')
else:
a = 0
# 打开数据库连接
db = pymysql.connect(host='MySQL服务器电脑外网IP
', port=3306, user='账号', passwd='密码', db='userbase') # MySQL服务器电脑外网IP可用百度查到
# db = pymysql.connect("localhost", "root", "root", "RUNOOB") # 本地host
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 查询语句
sql = "select * from USERLIST"
# 执行SQL语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
for row in results:
name = row[1]
pwd = row[2]
if name == en1_value and pwd == en2_value:
a = 1
messagebox.showinfo('登陆成功!!!', txt)
self.root.withdraw()
main()
# 关闭数据库连接
db.close()
if a == 0:
messagebox.showinfo('用户名或密码错误!!!', txt)
if __name__ == "__main__":
Login()
Python学习笔记_02:使用Tkinter连接MySQL数据库实现登陆注册功能