第035講:圖形使用者介面入門:EasyGui | 課後測試題及答案
阿新 • • 發佈:2020-07-18
動動手
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)