• Python 自定义模块和包实现GUI(图形界面)登录界面


    上一篇:Python 自定义模块和包设计英语生词本(文件版)-CSDN博客

    紧接上一篇博文,当我们熟练掌握自定义模块和包、掌握文件的的读取与写入、掌握正则表达式内置模块"re"、掌握GUI(图形界面)的部分组件后,接着我们将要以上的知识点结合起来,设计一个GUI(图形界面)登录界面。且看我如何一步两步......完成设计吧。

    一、作品展示

    1.运行结果

    2.设计代码

    1. """
    2. 账户密码登录
    3. """
    4. # 通配符 '*'
    5. __all__ = ['main']
    6. # 获取验证码
    7. def getVerifyCode(object):
    8. from 小功能包.验证码 import verify_code
    9. object.set(verify_code.verify_code(6))
    10. return verify_code.verify_code(6)
    11. # 读取文件数据
    12. def readFileData():
    13. from 小功能包.文件操作 import ReadFileData as read
    14. data = read.readlinesData(userDataPath, [])
    15. if data != '文件不存在':
    16. global userData
    17. userData = data
    18. # 查找账户
    19. def findID(id):
    20. readFileData() # 读取文件数据
    21. # 查找账户
    22. for i in userData:
    23. if i.strip('\n').split(' ')[0] == id:
    24. return i.strip('\n').split(' ')
    25. return None
    26. # 账户登录
    27. def IDenter(ID, password, inputVerify, verifyCode, label):
    28. # print(ID.get(), password.get(), inputVerify.get(), verifyCode.get(), label.get())
    29. # 查找账户是否存在
    30. data = findID(ID.get())
    31. # 校对账户
    32. if data:
    33. # 校对密码
    34. if data[1] == password.get():
    35. # 校对验证码
    36. import re
    37. if re.findall(verifyCode.get(), inputVerify.get(), re.I):
    38. label.set('登录成功')
    39. # 初始化输入框
    40. ID.set('')
    41. password.set('')
    42. inputVerify.set('')
    43. # 验证码输入错误
    44. else:
    45. label.set('验证码输入错误')
    46. inputVerify.set('')
    47. # 密码输入错误
    48. else:
    49. label.set('密码输入错误')
    50. password.set('')
    51. # 账户输入错误
    52. else:
    53. label.set('账户名输入错误')
    54. ID.set('')
    55. getVerifyCode(verifyCode) # 更新验证码
    56. # 账户注册
    57. def IDregister(ID, password, inputVerify, verifyCode, label):
    58. # print(ID.get(), password.get(), inputVerify.get(), verifyCode.get(), label.get())
    59. # 查找账户是否存在
    60. data = findID(ID.get())
    61. # 防止账户密码输入特殊字符空格' '
    62. import re
    63. IDdata = re.findall(r'\W', ID.get())
    64. passwordData = re.findall(r'\W', password.get())
    65. if ' ' in IDdata:
    66. label.set('账户名不能使用空格')
    67. ID.set('')
    68. elif ' ' in passwordData:
    69. label.set('密码不能使用空格')
    70. password.set('')
    71. # 防止输入内容为空''
    72. elif not ID.get():
    73. label.set('账户名不能为空')
    74. elif not password.get():
    75. label.set('密码不能为空')
    76. # 校对账户
    77. elif not data:
    78. # 校对验证码
    79. import re
    80. if re.findall(verifyCode.get(), inputVerify.get(), re.I):
    81. # 保存到列表中
    82. userData.append(f'{ID.get()} {password.get()}')
    83. label.set('账户注册成功')
    84. # 初始化输入框
    85. ID.set('')
    86. password.set('')
    87. inputVerify.set('')
    88. # 更新文件数据
    89. from 小功能包.文件操作 import WriteFileData
    90. WriteFileData.writelinesData(userDataPath, userData)
    91. # 验证码输入错误
    92. else:
    93. label.set('验证码输入错误')
    94. inputVerify.set('')
    95. # 账户输入错误
    96. else:
    97. label.set('该账户名已注册')
    98. ID.set('')
    99. getVerifyCode(verifyCode) # 更新验证码
    100. # 全局变量
    101. userDataPath = '.\\..\\user data\\data.txt'
    102. userData = []
    103. # 主函数
    104. def main():
    105. import tkinter as tk
    106. base = tk.Tk() # 新建窗口
    107. base.title('账户密码登录') # 标题
    108. # 全局变量
    109. labelData = tk.StringVar() # 标签数据
    110. ID = tk.StringVar() # 账号数据
    111. password = tk.StringVar() # 密码数据
    112. inputVerifyCode = tk.StringVar() # 输入验证码数据
    113. verifyCode = tk.StringVar() # 验证码
    114. # 初始化设置
    115. verifyCode.set(getVerifyCode(verifyCode)) # 初始验证码
    116. labelData.set('欢迎来到【周华2022博客】客户端')
    117. # 标签提示语
    118. textLabel = tk.Label(base, textvariable=labelData, height=2) # 文本标签
    119. textLabel.pack()
    120. # 账号 ----------------------------------------------------------------------------
    121. IDframe = tk.Frame(base, pady=8) # 账号框架
    122. IDframe.pack()
    123. # 账号标签
    124. IDlabel = tk.Label(IDframe, text='账户')
    125. IDlabel.pack(side=tk.LEFT)
    126. # 账号文本框
    127. IDentry = tk.Entry(IDframe, text=ID, highlightthickness=1)
    128. IDentry.pack(side=tk.RIGHT)
    129. # 密码 -----------------------------------------------------------------------------
    130. passwordFrame = tk.Frame(base, pady=8) # 密码框架
    131. passwordFrame.pack()
    132. # 密码标签
    133. passwordLabel = tk.Label(passwordFrame, text='密码')
    134. passwordLabel.pack(side=tk.LEFT)
    135. # 密码文本框
    136. passwordEntry = tk.Entry(passwordFrame, text=password, highlightthickness=1, show='*')
    137. passwordEntry.pack(side=tk.RIGHT)
    138. # 验证码 -----------------------------------------------------------------------------
    139. verifyFrame = tk.Frame(base, pady=6) # 验证码框架
    140. verifyFrame.pack()
    141. # 验证码标签
    142. verifyLabel = tk.Label(verifyFrame, text='验证码')
    143. verifyLabel.pack(side=tk.LEFT)
    144. # 验证码文本框
    145. verifyEntry = tk.Entry(verifyFrame, text=inputVerifyCode, highlightthickness=1, width=9)
    146. verifyEntry.pack(side=tk.LEFT)
    147. # 验证码更新1
    148. image = tk.PhotoImage(file='.\\..\\photo\\刷新.png')
    149. updataButton = tk.Button(verifyFrame, textvariable=verifyCode, relief=tk.FLAT)
    150. updataButton.config(image=image, width=20, height=20)
    151. updataButton.config(command=lambda: getVerifyCode(verifyCode))
    152. updataButton.pack(side=tk.LEFT)
    153. # 验证码更新2
    154. verifyUpdata = tk.Button(verifyFrame, textvariable=verifyCode, relief=tk.FLAT)
    155. verifyUpdata.config(command=lambda: getVerifyCode(verifyCode), width=7)
    156. verifyUpdata.pack()
    157. # 按钮 ------------------------------------------------------------------------------
    158. buttonFrame = tk.Frame(base, padx=60, pady=10) # 按钮框架
    159. buttonFrame.pack()
    160. # 账号登录按钮
    161. enterButton = tk.Button(buttonFrame, text='登录')
    162. enterButton.config(command=lambda: IDenter(ID, password, inputVerifyCode, verifyCode, labelData))
    163. enterButton.pack(side=tk.LEFT)
    164. # 空白标签(隔开按钮)
    165. blankLabel = tk.Label(buttonFrame, width=6)
    166. blankLabel.pack(side=tk.LEFT)
    167. # 账号注册按钮
    168. registerButton = tk.Button(buttonFrame, text='注册')
    169. registerButton.config(command=lambda: IDregister(ID, password, inputVerifyCode, verifyCode, labelData))
    170. registerButton.pack()
    171. base.mainloop() # 循环运行窗口
    172. # 代码测试
    173. if __name__ == '__main__':
    174. main()

    3.模块设计,当前小程序只用了两个模块:文件操作.py、验证码.py

    ① 模块一:文件操作.py

    1. """
    2. 文件操作模块
    3. """
    4. # 通配符'*'变量定义
    5. __all__ = ['main']
    6. # 获取绝对路径 ------------------------------------------------------------------------
    7. __all__.append('getAbsPath') # 通配符'*'添加元素
    8. def getAbsPath(path):
    9. import os, sys
    10. return os.path.abspath(sys.path[0]+path)
    11. # 新建目录文件 ------------------------------------------------------------------------
    12. __all__.append('makeDirFile') # 通配符'*'添加元素
    13. def makeDirFile(path):
    14. # 路径分割
    15. dirPath = ''
    16. for i in path.split('\\')[:-1:]:
    17. dirPath += i + '\\'
    18. makeDir(dirPath) # 新建目录
    19. makeFile(path) # 新建文件
    20. # 新建目录 -----------------------------------------------------------------------------
    21. __all__.append('makeDir') # 通配符'*'添加元素
    22. def makeDir(path):
    23. path = getAbsPath(path) # 获取绝对路径
    24. # 判断文件是否存在,否则新建目录
    25. import os
    26. if not os.path.exists(path):
    27. os.mkdir(path)
    28. # 新建文件 -----------------------------------------------------------------------------
    29. __all__.append('makeFile') # 通配符'*'添加元素
    30. def makeFile(path):
    31. path = getAbsPath(path) # 获取绝对路径
    32. # 判断文件是否存在,否则新建文件
    33. import os
    34. if not os.path.exists(path):
    35. file = open(file=path, mode='w')
    36. file.close()
    37. # 读取文件数据 =========================================================================
    38. __all__.append('ReadFileData') # 通配符'*'添加元素
    39. class ReadFileData:
    40. # 构造方法
    41. def __init__(self):
    42. pass
    43. # 读取文件行数据,返回读取的数据 --------------------------------------------------------
    44. @classmethod
    45. def readlinesData(cls, path, container):
    46. data = container
    47. if container == list(): # 变量赋值
    48. data = []
    49. path = getAbsPath(path) # 获取绝对路径
    50. # 判断文件是否存在
    51. import os
    52. if not os.path.exists(path):
    53. return '文件不存在'
    54. # 读取文件数据
    55. with open(path, encoding='utf-8') as file:
    56. for i in file:
    57. if container == str(): # 字符串容器
    58. data += i
    59. elif container == list(): # 列表容器
    60. data.append(i)
    61. else:
    62. print('存储读取数据类型必须为字符串str()或者列表list()')
    63. return data
    64. # 读取文件行数据,返回读取的数据 --------------------------------------------------------
    65. @classmethod
    66. def readSplitData(cls, path, split, container):
    67. if container == list():
    68. data = []
    69. elif container == dict():
    70. data = dict()
    71. path = getAbsPath(path) # 获取绝对路径
    72. # 判断文件是否存在
    73. import os
    74. if not os.path.exists(path):
    75. return '文件不存在'
    76. # 读取文件数据
    77. with open(path, encoding='utf-8') as file:
    78. for i in file:
    79. if container == list():
    80. data.append(i.split(split))
    81. elif container == dict():
    82. data[i.split(split)[0]] = i.split(split)[1::]
    83. else:
    84. print('存储读取数据类型必须列表list()或者字典dict()')
    85. return data
    86. # 写入文件数据 =========================================================================
    87. __all__.append('WriteFileData') # 通配符'*'添加元素
    88. class WriteFileData:
    89. # 构造方法
    90. def __init__(self):
    91. pass
    92. # 写入文件行数据 --------------------------------------------------------------------
    93. @classmethod
    94. def writelinesData(cls, path, data):
    95. makeDirFile(path) # 新建目录和文件
    96. path = getAbsPath(path) # 获取绝对路径
    97. # 写入文件数据
    98. with open(path, 'w', encoding='utf-8') as file:
    99. if type(data) == str:
    100. file.write(data)
    101. if data[-1] != '\n':
    102. file.write('\n')
    103. elif type(data) == list:
    104. for i in data:
    105. file.write(i)
    106. if i[-1] != '\n' and i == data[-1]:
    107. file.write('\n')
    108. else:
    109. print('写入数据类型必须为字符串str()或者列表list()')
    110. # 写入文件行数据 --------------------------------------------------------------------
    111. @classmethod
    112. def writeSplitData(cls, path, data, split):
    113. makeDirFile(path) # 新建目录和文件
    114. path = getAbsPath(path) # 获取绝对路径
    115. # 写入文件数据
    116. with open(path, 'w', encoding='utf-8') as file:
    117. if type(data) == list:
    118. for i in data:
    119. for j in i:
    120. file.write(j)
    121. if i[-1] != j:
    122. file.write(split)
    123. if j[-1] != '\n' and i[-1] == j:
    124. file.write('\n')
    125. elif type(data) == dict:
    126. for i, j in data.items():
    127. file.write(i)
    128. for k in j:
    129. file.write(split + k)
    130. if k == j[-1] and k[-1] != '\n':
    131. file.write('\n')
    132. else:
    133. print('写入数据类型必须为列表list()或者字典dict()')
    134. # 主函数 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    135. def main():
    136. print(ReadFileData.readlinesData('.\\..\\十六进制颜色码.txt', ''))
    137. print(ReadFileData.readSplitData('.\\..\\十六进制颜色码.txt', '、', dict()))
    138. data = ReadFileData.readlinesData('.\\..\\十六进制颜色码.txt', '')
    139. WriteFileData.writelinesData('.\\..\\123\\456.txt', data)
    140. data2 = ReadFileData.readSplitData('.\\..\\十六进制颜色码.txt', '、', dict())
    141. WriteFileData.writeSplitData('.\\..\\456\\789.txt', data2, '(*)')
    142. # 代码测试
    143. if __name__ == '__main__':
    144. main()
    145. else:
    146. print(f'导入"{__name__}"模块')

    ② 模块二:验证码.py

    1. """
    2. 获取验证码模块
    3. """
    4. # 定义此属性是为了方便使用通配符‘*’
    5. __all__ = ['main']
    6. # 获取验证码 ===================================================================
    7. __all__.append('verify_code') # 通配符'*'添加元素
    8. class verify_code:
    9. __int_list = [] # 用于存储数字
    10. __str_list = [] # 用于存储字母
    11. __all_list = [] # 用于存储数字和字母
    12. # 列表添加元素 --------------------------------------------------------------
    13. @classmethod
    14. def __list_append(cls):
    15. # 初始化清空
    16. cls.__int_list = []
    17. cls.__str_list = []
    18. cls.__all_list = []
    19. # 获取0-9数字
    20. for i in range(10):
    21. cls.__int_list.append(str(i))
    22. # 获取26个大小写字母
    23. for i in range(26):
    24. cls.__str_list.append(chr(ord('a')+i))
    25. cls.__str_list.append(chr(ord('A')+i))
    26. # 把数字和字母列表集合到一起
    27. for i in range(5):
    28. cls.__all_list.extend(cls.__int_list)
    29. cls.__all_list.extend(cls.__str_list)
    30. # 获取列表元素 --------------------------------------------------------------
    31. @classmethod
    32. def get_list_element(cls, list, int):
    33. import random
    34. code = ''
    35. for i in range(int):
    36. code += random.choice(list)
    37. return code
    38. # 纯获取数字验证码 -------------------------------------------------------------
    39. @classmethod
    40. def int_sequence(cls, int=6):
    41. cls.__list_append() # 列表添加元素
    42. # 获取列表的元素
    43. return cls.get_list_element(cls.__int_list, int)
    44. # 获取纯字母验证码 -------------------------------------------------------------
    45. @classmethod
    46. def str_sequence(cls, int=6):
    47. cls.__list_append() # 列表添加元素
    48. # 获取列表的元素
    49. return cls.get_list_element(cls.__str_list, int)
    50. # 获取数字和字母验证码 --------------------------------------------------------
    51. @classmethod
    52. def verify_code(cls, int=6):
    53. cls.__list_append() # 列表添加元素
    54. # 获取列表的元素
    55. return cls.get_list_element(cls.__all_list, int)
    56. # 主函数 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    57. def main():
    58. print(verify_code.int_sequence())
    59. print(verify_code.str_sequence())
    60. print(verify_code.verify_code())
    61. # 代码测试 ==========================================================================
    62. if __name__ == '__main__':
    63. main()
    64. else:
    65. print(f'导入"{__name__}"模块')

    4.图片文件:刷新.png(大小:20x20)

    作者:周华

    创作日期:2023/10/26

  • 相关阅读:
    Mybatis——数据库交互数据的注解和标签
    vue+element模仿实现PC端网易云,对接第三方接口
    欣赏绍兴的美景,感受OLED透明拼接屏带来的视觉盛宴
    Spring AI 接入OpenAI实现文字生成图片功能
    Ubuntu22.04安装libudev-dev时的Bug
    造车先做三蹦子-之二:自制数据集(5x5数据集)230102
    淘宝、1688、拼多多、苏宁商品详情API接口(网络爬虫数据示例)
    向量嵌入:AutoGPT的幻觉解法?
    LeetCode——面试题 02.01. 移除重复节点
    使用Redis实现延时队列
  • 原文地址:https://blog.csdn.net/zhouhua2022/article/details/134066734