第035讲:图形用户界面入门:EasyGui | 课后测试题及答案
动动手
0. 先练练手,把我们的刚开始的那个猜数字小游戏加上界面吧?
1 import random 2 import easygui as g 3 4 g.msgbox("嗨,欢迎进入第一个界面小游戏^_^") 5 secret = random.randint(1,10) 6 7 msg = "不妨猜一下小甲鱼现在心里想的是哪个数字(1~10):" 8 title = "数字小游戏" 9 guess = g.integerbox(msg, title, lowerbound=1, upperbound=10) 10 11 while True: 12 if guess == secret: 13 g.msgbox("我草,你是小甲鱼心里的蛔虫吗?!") 14 g.msgbox("哼,猜中了也没有奖励!") 15 break 16 else: 17 if guess > secret: 18 g.msgbox("哥,大了大了~~~") 19 else: 20 g.msgbox("嘿,小了,小了~~~") 21 guess = g.integerbox(msg, title, lowerbound=1, upperbound=10) 22 23 g.msgbox("游戏结束,不玩啦^_^")
1. 实现一个用于登记用户账号信息的界面(如果是带 * 号的必填项,要求一定要有输入并且不能是空格)。
代码:
1 # 实现一个用于登记用户账号信息的界面(如果是带 * 号的必填项,要求一定要有输入并且不能是空格) 2 import easygui as g 3 4 msg = "请填写以下联系方式" 5 title = "账号中心" 6 #这边创建的填入信息标题是空格开头的 7 fieldNames = [" *用户名", " *真实姓名", " 固定电话", " *手机号码", " QQ", " *E-mail"] 8 fieldValues = [] 9 fieldValues = g.multenterbox(msg, title, fieldNames) 10 11 # 如果用户输入的值比选项少的话,则返回列表中的值用空字符串填充用户为输入的选项。 所以将box返回的值收集在一个列表里 12 13 # 如果用户取消操作,则返回域中的列表的值或者 None 值 14 15 #效果图上的提示是填入不符后才显示出来的 16 print(fieldValues) 17 while 1: 18 if fieldValues == None: 19 break 20 #fieldValues初始是空列表,你啥都没填,按下OK后,fieldValues也是有值的,返回的是6个'' 21 # 所以这个条件是判断在输入框中最后你单击的是确定还是取消 22 errmsg = "" 23 for i in range(len(fieldNames)): 24 option = fieldNames[i].strip() 25 if fieldValues[i].strip() == "" and option[0] == "*": 26 errmsg += ('【%s】为必填项。\n\n' % fieldNames[i]) 27 if errmsg == "": 28 break 29 fieldValues = g.multenterbox(errmsg, title, fieldNames, fieldValues) 30 31 print("用户资料如下:%s" % str(fieldValues))
2. 提供一个文件夹浏览框,让用户选择需要打开的文本文件,打开并显示文件内容
# 2. 提供一个文件夹浏览框,让用户选择需要打开的文本文件,打开并显示文件内容。 import easygui as g # 我们这里想到textbox()函数默认会以比例字体(参数 codebox=True 设置为等宽字体)来显示文本内容(自动换行),这个函数适合用于显示一般的书面文字。 # textbox(msg='', title=' ', text='', codebox=False, callback=None, run=True) import os file_path = g.fileopenbox(default='*.txt') # fileopenbox(msg=None, title=None, default='*', filetypes=None, multiple=False) # fileopenbox() 函数用于提供一个对话框,返回用户选择的文件名(带完整路径哦),如果用户选择 “Cancel” 则返回 None。 # 关于 default 参数的设置方法: # default 参数指定一个默认路径,通常包含一个或多个通配符。 # 如果设置了 default 参数,fileopenbox() 显示默认的文件路径和格式。 # default 默认的参数是 '*',即匹配所有格式的文件。 with open(file_path) as f: title = os.path.basename(file_path) #os.path.basename(path) 返回文件名 msg = '文件【%s】的内容如下:' % title text = f.read() g.textbox(msg, title, text)
3. 在上一题的基础上增强功能:当用户点击“OK”按钮的时候,比较当前文件是否修改过,如果修改过,则提示“覆盖保存”、”放弃保存”或“另存为…”并实现相应的功能。
(提示:解决这道题可能需要点耐心,因为你有可能会被一个小问题卡住,但请坚持,自己想办法找到这个小问题所在并解决它!)
点击OK按钮后会有什么结果呢?
怎么比较当前文件是否被修改过了呢?
1 # 3. 在上一题的基础上增强功能:当用户点击“OK”按钮的时候,比较当前文件是否修改过,如果修改过,则提示“覆盖保存”、”放弃保存”或“另存为…”并实现相应的功能。 2 import easygui as g 3 import os 4 5 file_path = g.fileopenbox(default="*.txt") 6 7 with open(file_path) as old_file: 8 title = os.path.basename(file_path) 9 msg = "文件【%s】的内容如下:" % title 10 text = old_file.read() 11 text_after = g.textbox(msg, title, text) # textbox()显示文本时是可以修改的,但是对原文件是没有改动,只是显示的时候 12 print(text_after) 13 14 if text != text_after[:-1]: 15 # textbox 的返回值会追加一个换行符 16 choice = g.buttonbox("检测到文件内容发生改变,请选择以下操作:", "警告", ("覆盖保存", "放弃保存", "另存为...")) 17 # buttonbox(msg='', title=' ', choices=('Button[1]', 'Button[2]', 'Button[3]'), image=None, images=None, default_choice=None, cancel_choice=None, callback=None, run=True) 18 19 # 可以使用buttonbox()定义自己的一组按钮,buttonbox()会显示一组由你自定义的按钮。 20 # 当用户点击任意一个按钮的时候,buttonbox()返回按钮的文本内容。 21 # 如果用户点击取消或者关闭窗口,那么会返回默认选项(第一个选项)。 22 23 if choice == "覆盖保存": 24 with open(file_path, "w") as old_file: # 直接以‘w 写入,由于是已经存在文件,写入就是覆盖 25 old_file.write(text_after[:-1]) 26 if choice == "放弃保存": 27 pass 28 if choice == "另存为...": 29 another_path = g.filesavebox(default=".txt") 30 if os.path.splitext(another_path)[1] != '.txt': # os.path.splitext(path) 分割路径中的文件名与拓展名 31 another_path += '.txt' 32 with open(another_path, "w") as new_file: 33 new_file.write(text_after[:-1]) 34 35 # filesavebox(msg=None, title=None, default='', filetypes=None) 36 # filesavebox() 函数提供一个对话框,让用于选择文件需要保存的路径(带完整路径哦),如果用户选择 “Cancel” 则返回 None。 37 # default 参数应该包含一个文件名(例如当前需要保存的文件名),当然也可以设置为空的,或者包含一个文件格式掩码的通配符。 38 # filetypes 参数的设置方法请参考 fileopenbox() 函数。
4. 写一个程序统计你当前代码量的总和,并显示离十万行代码量还有多远?
- 要求一:递归搜索各个文件夹
- 要求二:显示各个类型的源文件和源代码数量
- 要求三:显示总行数与百分比
1 # 写一个程序统计你当前代码量的总和,并显示离十万行代码量还有多远? 2 # 要求一:递归搜索各个文件夹 3 # 要求二:显示各个类型的源文件和源代码数量 4 # 要求三:显示总行数与百分比 5 6 7 import easygui as g 8 import os 9 10 def show_result(start_dir): 11 lines = 0 12 total = 0 13 text = '' 14 15 for i in source_list: 16 lines = source_list[i] 17 total += lines 18 text += "【%s】源文件 %d 个,源代码 %d 行\n" % (i, file_list[i], lines) 19 20 title = '统计结果' 21 msg = '您目前共累计敲了 %d 行代码,完成进度: %2.f %%\n离10万行代码还差 %d 行,请继续努力!' % (total, total/1000, 100000 - total) 22 g.textbox(msg, title, text) 23 24 25 def calc_code(file_name): 26 lines = 0 27 with open(file_name) as f: 28 print('正在分析文件:%s...' % file_name) 29 try: 30 for each_line in f: 31 lines += 1 32 33 except UnicodeDecodeError: 34 pass # 不可避免会遇到格式不兼容的文件,这里忽略掉...... 35 36 return lines 37 38 def search_file(start_dir): 39 os.chdir(start_dir) 40 41 for each_file in os.listdir(os.curdir): 42 ext = os.path.splitext(each_file)[1] 43 if ext in target: 44 lines = calc_code(each_file) # 统计行数 45 # 还记得异常的用法吗?如果字典中不存,抛出KeyError,则添加字典键 46 # 统计文件数 47 try: 48 file_list[ext] += 1 49 except KeyError: 50 file_list[ext] = 1 51 52 #统计源代码行数 53 54 try: 55 source_list[ext] += lines 56 57 except KeyError: 58 source_list[ext] = lines 59 60 if os.path.isdir(each_file): 61 search_file(each_file) # 递归调用 62 os.chdir(os.pardir) # 递归调用完切记返回上一层目录 63 64 target = ['.c', '.cpp', '.py', '.cc', '.java', '.pas', '.asm'] 65 file_list = {} 66 source_list = {} 67 68 g.msgbox('请打开您存放所以代码的文件夹......', '统计代码量') 69 path = g.diropenbox('请选择您的代码库:') 70 71 search_file(path) 72 show_result(path)
作者:Agiroy_70
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
博主的文章主要是记录一些学习笔记、作业等。文章来源也已表明,由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。
博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的文章,请原谅博主成为一个无耻的文档搬运工!