1. 程式人生 > >第035講:圖形使用者介面入門:EasyGui

第035講:圖形使用者介面入門:EasyGui

0. 請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!

圖形使用者介面入門:EasyGui,也就是我們常說的GUI程式設計,(GUI:Graphical User Interface)。

easygui官網:http://easygui.sourceforge.net/

easygui各功能的使用請查閱:EasyGui學習文件

動動手

0. 先練練手,把我們的剛開始的那個猜數字小遊戲加上介面吧?

import random
import easygui as g

g.msgbox("嗨,歡迎進入第一個介面小遊戲^_^")
secret = random.randint(1,10)

msg = "不妨猜一下小甲魚現在心裡想的是哪個數字(1~10):"
title = "數字小遊戲"
guess = g.integerbox(msg, title, lowerbound=1, upperbound=10)

while True:
    if guess == secret:
        g.msgbox("我草,你是小甲魚心裡的蛔蟲嗎?!")
        g.msgbox("哼,猜中了也沒有獎勵!")
        break
    else:
        if guess > secret:
            g.msgbox("哥,大了大了~~~")
        else:
            g.msgbox("嘿,小了,小了~~~")   
        guess = g.integerbox(msg, title, lowerbound=1, upperbound=10)
            
g.msgbox("遊戲結束,不玩啦^_^")

1. 如下圖,實現一個用於登記使用者賬號資訊的介面(如果是帶 * 號的必填項,要求一定要有輸入並且不能是空格)。

import easygui as g

msg = "請填寫以下聯絡方式"
title = "賬號中心"
fieldNames = [" *使用者名稱", " *真實姓名", "  固定電話", " *手機號碼", "  QQ", " *E-mail"]
fieldValues = []
fieldValues = g.multenterbox(msg,title, fieldNames)

while 1:
    if fieldValues == None:
        break
    errmsg = ""
    for i in range(len(fieldNames)):
        option = fieldNames[i].strip()
        if fieldValues[i].strip() == "" and option[0] == "*":
            errmsg += ('【%s】為必填項。\n\n' % fieldNames[i])
    if errmsg == "":
        break
    fieldValues = g.multenterbox(errmsg, title, fieldNames, fieldValues)

print("使用者資料如下:%s" % str(fieldValues))
    

實現效果如下:

2. 提供一個資料夾瀏覽框,讓使用者選擇需要開啟的文字檔案,開啟並顯示檔案內容。

import easygui as g
import os

file_path = g.fileopenbox(default="*.txt")

with open(file_path) as f:
    title = os.path.basename(file_path)
    msg = "檔案【%s】的內容如下:" % title
    text = f.read()
    g.textbox(msg, title, text)

3. 在上一題的基礎上增強功能:當用戶點選“OK”按鈕的時候,比較當前檔案是否修改過,如果修改過,則提示“覆蓋儲存”、”放棄儲存”或“另存為…”並實現相應的功能。

(提示:解決這道題可能需要點耐心,因為你有可能會被一個小問題卡住,但請堅持,自己想辦法找到這個小問題所在並解決它!)

答:這道題會出現的一個小問題就是 easygui.textbox 函式會在返回的字串後邊追加一個行結束符(“\n”),因此在比較字串是否發生改變的時候我們需要人工將這個行結束符忽略。

import easygui as g
import os

file_path = g.fileopenbox(default="*.txt")

with open(file_path) as old_file:
    title = os.path.basename(file_path)
    msg = "檔案【%s】的內容如下:" % title
    text = old_file.read()
    text_after = g.textbox(msg, title, text)
    
if text != text_after[:-1]:
    # textbox 的返回值會追加一個換行符
    choice = g.buttonbox("檢測到檔案內容發生改變,請選擇以下操作:", "警告", ("覆蓋儲存", "放棄儲存", "另存為..."))
    if choice == "覆蓋儲存":
        with open(file_path, "w") as old_file:
            old_file.write(text_after[:-1])
    if choice == "放棄儲存":
        pass
    if choice == "另存為...":
        another_path = g.filesavebox(default=".txt")
        if os.path.splitext(another_path)[1] != '.txt':
            another_path += '.txt'
        with open(another_path, "w") as new_file:
            new_file.write(text_after[:-1])

4. 寫一個程式統計你當前程式碼量的總和,並顯示離十萬行程式碼量還有多遠?

  • 要求一:遞迴搜尋各個資料夾
  • 要求二:顯示各個型別的原始檔和原始碼數量
  • 要求三:顯示總行數與百分比

截圖1:

截圖2:

import easygui as g
import os

def show_result(start_dir):
    lines = 0
    total = 0
    text = ""

    for i in source_list:
        lines = source_list[i]
        total += lines
        text += "【%s】原始檔 %d 個,原始碼 %d 行\n" % (i, file_list[i], lines)
    title = '統計結果'
    msg = '您目前共累積編寫了 %d 行程式碼,完成進度:%.2f %%\n離 10 萬行程式碼還差 %d 行,請繼續努力!' % (total, total/1000, 100000-total)
    g.textbox(msg, title, text)

def calc_code(file_name):
    lines = 0
    with open(file_name) as f:
        print('正在分析檔案:%s ...' % file_name)
        try:
            for each_line in f:
                lines += 1
        except UnicodeDecodeError:
            pass # 不可避免會遇到格式不相容的檔案,這裡忽略掉......
    return lines

def search_file(start_dir) :
    os.chdir(start_dir)
    
    for each_file in os.listdir(os.curdir) :
        ext = os.path.splitext(each_file)[1]
        if ext in target :
            lines = calc_code(each_file) # 統計行數
            # 還記得異常的用法嗎?如果字典中不存,丟擲 KeyError,則新增字典鍵
            # 統計檔案數
            try:
                file_list[ext] += 1
            except KeyError:
                file_list[ext] = 1
            # 統計原始碼行數
            try:
                source_list[ext] += lines
            except KeyError:
                source_list[ext] = lines
            
        if os.path.isdir(each_file) :
            search_file(each_file) # 遞迴呼叫
            os.chdir(os.pardir) # 遞迴呼叫後切記返回上一層目錄
            
target = ['.c', '.cpp', '.py', '.cc', '.java', '.pas', '.asm']
file_list = {}
source_list = {}

g.msgbox("請開啟您存放所有程式碼的資料夾......", "統計程式碼量")
path = g.diropenbox("請選擇您的程式碼庫:")

search_file(path)
show_result(path)