習(xí)日記10)
圖形用戶界面GUI12.1 GUI 概述12.1.1 什么是 GUIGUIGraphical User Interface圖形用戶界面是程序與用戶交互的一種方式通過(guò)窗口、按鈕、文本框、菜單等可視化控件來(lái)接收用戶輸入和顯示輸出相比命令行界面CLI更直觀、更友好。12.1.2 Python 的 GUI 工具包本章介紹Tkinter因?yàn)樗?Python 自帶的開(kāi)箱即用。12.2 第一個(gè) Tkinter 程序12.2.1 創(chuàng)建主窗口import tkinter as tk # 創(chuàng)建主窗口 root tk.Tk() root.title(我的第一個(gè)GUI程序) # 進(jìn)入主事件循環(huán) root.mainloop()代碼解讀tk.Tk()創(chuàng)建主窗口對(duì)象title()設(shè)置窗口標(biāo)題mainloop()進(jìn)入事件循環(huán)等待用戶操作點(diǎn)擊、按鍵等12.2.2 添加控件import tkinter as tk root tk.Tk() root.title(按鈕示例) # 創(chuàng)建按鈕控件 btn tk.Button() btn[text] 點(diǎn)擊我 # 設(shè)置按鈕文本 btn.pack() # 布局——將按鈕放入窗口 root.mainloop()代碼解讀Button()創(chuàng)建按鈕控件pack()布局管理器將控件放入窗口控件的屬性可以像字典一樣訪問(wèn)和修改12.2.3 添加事件響應(yīng)import tkinter as tk def on_click(): print(按鈕被點(diǎn)擊了) root tk.Tk() root.title(事件響應(yīng)示例) btn tk.Button() btn[text] 點(diǎn)擊我 btn[command] on_click # 綁定點(diǎn)擊事件 btn.pack() root.mainloop()代碼解讀command屬性綁定按鈕被點(diǎn)擊時(shí)調(diào)用的函數(shù)點(diǎn)擊按鈕時(shí)on_click()函數(shù)自動(dòng)執(zhí)行12.2.4 使用構(gòu)造函數(shù)配置import tkinter as tk def on_click(): print(按鈕被點(diǎn)擊了) root tk.Tk() root.title(簡(jiǎn)潔寫(xiě)法) # 在創(chuàng)建時(shí)直接配置屬性 btn tk.Button(text點(diǎn)擊我, commandon_click) btn.pack() root.mainloop()12.2.5 使用config()方法import tkinter as tk root tk.Tk() btn tk.Button() btn.config(text點(diǎn)擊我, commandlambda: print(Clicked!)) btn.pack() root.mainloop()12.3 常用控件12.3.1 標(biāo)簽Labelimport tkinter as tk root tk.Tk() root.title(標(biāo)簽示例) # 創(chuàng)建文本標(biāo)簽 label tk.Label(text這是一個(gè)標(biāo)簽, font(Arial, 16), fgblue) label.pack() root.mainloop()12.3.2 文本框EntryEntry用于輸入單行文本。import tkinter as tk def show_text(): print(entry.get()) # 獲取輸入框內(nèi)容 root tk.Tk() root.title(輸入框示例) entry tk.Entry() entry.pack() btn tk.Button(text提交, commandshow_text) btn.pack() root.mainloop()12.3.3 文本區(qū)域Text / ScrolledTextText用于多行文本輸入ScrolledText自帶滾動(dòng)條。import tkinter as tk from tkinter.scrolledtext import ScrolledText root tk.Tk() root.title(文本區(qū)域示例) # 創(chuàng)建可滾動(dòng)文本區(qū)域 text_area ScrolledText(height10, width40) text_area.pack() def get_text(): content text_area.get(1.0, tk.END) # 獲取全部文本 print(content) btn tk.Button(text獲取內(nèi)容, commandget_text) btn.pack() root.mainloop()get()方法的參數(shù)1.0第1行第0列文件開(kāi)頭tk.END文本末尾tk.INSERT當(dāng)前光標(biāo)位置12.3.4 按鈕Buttonimport tkinter as tk root tk.Tk() # 創(chuàng)建帶文字和顏色的按鈕 btn1 tk.Button(text普通按鈕, bglightblue) btn1.pack() # 創(chuàng)建帶圖標(biāo)的按鈕需要圖像文件 # img tk.PhotoImage(fileicon.png) # btn2 tk.Button(text帶圖標(biāo), imageimg, compoundleft) # btn2.pack() root.mainloop()12.4 布局管理器布局管理器決定控件在窗口中的位置和大小。12.4.1pack()—— 堆疊布局pack()將控件依次堆疊在窗口中。import tkinter as tk root tk.Tk() # 默認(rèn)從上到下排列 tk.Button(text按鈕1).pack() tk.Button(text按鈕2).pack() tk.Button(text按鈕3).pack() root.mainloop()常用參數(shù)# 水平排列 tk.Button(text左, bgred).pack(sidetk.LEFT, padx5) tk.Button(text中, bggreen).pack(sidetk.LEFT, padx5) tk.Button(text右, bgblue).pack(sidetk.LEFT, padx5) # 填充和擴(kuò)展 tk.Button(text填充).pack(filltk.X, expandTrue)12.4.2grid()—— 網(wǎng)格布局grid()將控件放在表格網(wǎng)格中適合復(fù)雜布局。import tkinter as tk root tk.Tk() # 創(chuàng)建標(biāo)簽和輸入框?qū)?tk.Label(text用戶名).grid(row0, column0, stickye) tk.Entry().grid(row0, column1) tk.Label(text密碼).grid(row1, column0, stickye) tk.Entry().grid(row1, column1) tk.Button(text登錄).grid(row2, column0, columnspan2) root.mainloop()常用參數(shù)12.4.3place()—— 絕對(duì)定位place()直接指定控件的精確位置不推薦在不同分辨率下顯示效果差。import tkinter as tk root tk.Tk() root.geometry(300x200) tk.Button(text精確位置).place(x100, y80, width100, height30) root.mainloop()12.5 事件處理12.5.1 使用bind()綁定事件除了command屬性外Tkinter 提供bind()方法綁定更廣泛的事件。import tkinter as tk def on_click(event): print(f鼠標(biāo)點(diǎn)擊位置({event.x}, {event.y})) root tk.Tk() root.geometry(400x300) root.bind(Button-1, on_click) # 左鍵點(diǎn)擊 root.mainloop()12.5.2 常見(jiàn)事件12.5.3 事件對(duì)象屬性def on_event(event): print(f控件{event.widget}) print(fX坐標(biāo){event.x}) print(fY坐標(biāo){event.y}) print(f按鍵{event.keysym}) print(f字符{event.char})12.5.4 鍵盤(pán)事件示例import tkinter as tk root tk.Tk() def on_key(event): if event.keysym Escape: root.quit() else: print(f按下了{(lán)event.keysym}) root.bind(Key, on_key) root.focus_set() # 讓窗口獲得焦點(diǎn) root.mainloop()12.6 綜合示例簡(jiǎn)單的文本編輯器下面是一個(gè)包含打開(kāi)文件、保存文件、編輯文本功能的簡(jiǎn)單 GUI 文本編輯器。import tkinter as tk from tkinter.scrolledtext import ScrolledText from tkinter import messagebox class SimpleEditor: 簡(jiǎn)單的文本編輯器 def __init__(self): self.root tk.Tk() self.root.title(簡(jiǎn)易文本編輯器) # 文件名輸入框 self.filename tk.Entry(self.root) self.filename.pack(sidetk.LEFT, expandTrue, filltk.X, padx5, pady5) # 工具欄 toolbar tk.Frame(self.root) toolbar.pack(sidetk.TOP, filltk.X) tk.Button(toolbar, text打開(kāi), commandself.open_file).pack(sidetk.LEFT, padx2) tk.Button(toolbar, text保存, commandself.save_file).pack(sidetk.LEFT, padx2) # 文本編輯區(qū)域 self.text_area ScrolledText(self.root, height20) self.text_area.pack(expandTrue, filltk.BOTH, padx5, pady5) self.root.mainloop() def open_file(self): 打開(kāi)文件并顯示內(nèi)容 filename self.filename.get().strip() if not filename: messagebox.showwarning(警告, 請(qǐng)輸入文件名) return try: with open(filename, r, encodingutf-8) as f: content f.read() self.text_area.delete(1.0, tk.END) # 清空 self.text_area.insert(tk.INSERT, content) # 插入內(nèi)容 except FileNotFoundError: messagebox.showerror(錯(cuò)誤, f文件 {filename} 不存在) except Exception as e: messagebox.showerror(錯(cuò)誤, f讀取文件失敗{e}) def save_file(self): 保存當(dāng)前內(nèi)容到文件 filename self.filename.get().strip() if not filename: messagebox.showwarning(警告, 請(qǐng)輸入文件名) return try: content self.text_area.get(1.0, tk.END) with open(filename, w, encodingutf-8) as f: f.write(content) messagebox.showinfo(成功, 文件已保存) except Exception as e: messagebox.showerror(錯(cuò)誤, f保存文件失敗{e}) if __name__ __main__: SimpleEditor()運(yùn)行效果頂部輸入框輸入文件名點(diǎn)擊打開(kāi)加載文件內(nèi)容到文本區(qū)域編輯后點(diǎn)擊保存寫(xiě)入文件12.7 對(duì)話框12.7.1 消息框from tkinter import messagebox # 信息提示 messagebox.showinfo(標(biāo)題, 這是一條信息) # 警告 messagebox.showwarning(標(biāo)題, 這是一條警告) # 錯(cuò)誤 messagebox.showerror(標(biāo)題, 發(fā)生錯(cuò)誤) # 詢問(wèn)返回 yes 或 no result messagebox.askyesno(確認(rèn), 確定要?jiǎng)h除嗎) if result: print(用戶確認(rèn)) else: print(用戶取消) # 選擇返回 ok 或 cancel result messagebox.askokcancel(確認(rèn), 確定要繼續(xù)嗎)12.7.2 文件選擇對(duì)話框from tkinter import filedialog # 選擇文件打開(kāi) filename filedialog.askopenfilename( title選擇文件, filetypes[(文本文件, *.txt), (所有文件, *.*)] ) # 選擇文件保存 filename filedialog.asksaveasfilename( title保存文件, defaultextension.txt, filetypes[(文本文件, *.txt), (所有文件, *.*)] ) # 選擇目錄 dirname filedialog.askdirectory(title選擇目錄)12.7.3 顏色選擇對(duì)話框from tkinter import colorchooser color colorchooser.askcolor(title選擇顏色) # 返回 ((r, g, b), #rrggbb) 或 None if color: print(color[1]) # #ff0000