python學習筆記-GUI

#==========================GUI介紹==========================
#GraphicalUserInterface,
#GUI for Python: Tkinter, wxPython, PyQt

#    TKinter 綁定的是TK GUI工具集,用Python包裝的TCL代碼
#    PyGTK Tkinter的替代品
#    wxPython 跨平臺的Python GUI
# PyQt 跨平臺的,但商業授權可能有問題

# 推薦資料:
    # 辛星GUI, 辛星Python
    # Python GUI Programming cookbook
    # Tkinter reference a GUI for Python

#==========================Tkinter常用組件==========================
# 按鈕
    # Button:按鈕組件
    # RadioButton:單選框組件
    # CheckButton:選擇按鈕組件
    # Listbox:列表框組件
# 文本輸入組件
    # Entry:單行文本框組件
    # Text:多行文本框組件
# 標籤組件
    # Label:標籤組件,可以顯示圖片和文字
    # Message:標籤組件,可以根據內容將文字換行
# 菜單
    # Menu:菜單組件
    # MenuButton:菜單按鈕組件,可以使用Menu代替
#    滾動條
    # scale:滑塊組件
    # Scrollbar:滾動條組件
#    其他組件
    # Canvas:畫布組件
    # Frame:框架組件,將多個組件編組
    # Toplevel:創建子窗口容器組件

# 組件的大致使用步驟
    # 1、創建總面板
    # 2、創建面板上的各種組件
        # 1、指定組件的父組件,即依附關係
        # 2、利用相應的屬性對組件進行設置
        # 3、給組件安排佈局
    # 3、同步驟2相似,創建好多個組件
    # 4、最後,啓動總面板的消息循環
    
# Label實例:
    import tkinter
    # 創建總面板
    base = tkinter.Tk()
    # 負責標題
    base.wm_title("Label Test")
    # 支持屬性很多background, font, underline等
    # 第一個參數,制定所屬
    lb1= tkinter.Label(base, text="Python AI")
    # 給相應組件指定佈局
    lb1.pack()

    lb2= tkinter.Label(base, text="綠色背景", background="green")
    lb2.pack()

    lb3= tkinter.Label(base, text="藍色背景", background="blue")
    lb3.pack()

    base.mainloop()

# button實例:

    '''
    Button的屬性:

    anchor                 設置按鈕中文字的對其方式,相對於按鈕的中心位置
    background(bg)         設置按鈕的背景顏色
    foreground(fg)        設置按鈕的前景色(文字的顏色)
    borderwidth(bd)        設置按鈕邊框寬度
    cursor                設置鼠標在按鈕上的樣式
    command                設定按鈕點擊時觸發的函數
    bitmap                設置按鈕上顯示的位圖
    font                設置按鈕上文本的字體
    width                設置按鈕的寬度  (字符個數)
    height                設置按鈕的高度  (字符個數)
    state                設置按鈕的狀態
    text                設置按鈕上的文字
    image                設置按鈕上的圖片

    '''
    import tkinter
    def showLabel():
        global baseFrame
        # 在函數中定義了一個label
        # label的父組件是baseFrame
        lb = tkinter.Label(baseFrame, text="顯示Label")
        lb.pack()
    baseFrame = tkinter.Tk()
    # 生成一個按鈕
    # command參數指示,當按鈕被按下的時候,執行哪個函數
    btn = tkinter.Button(baseFrame, text="Show Label", command=showLabel)
    #btn = tkinter.Button(baseFrame, text="Show Label")
    btn.pack()
    baseFrame.mainloop()
    
#==========================組件佈局==========================
# 控制組件的擺放方式
# 三種佈局:
    # pack: 按照方位佈局
    # grid: 網格佈局
    # place: 按照座標佈局

#pack佈局
# 最簡單,代碼量最少,挨個擺放,默認從上倒下,系統自動設置
# 通用使用方式爲: 組件對象.pack(設置,,,,,,,)
    # side: 停靠方位, 可選值爲LEFT,TOP,RIGHT,BOTTON
    # fill: 填充方式,X,Y,BOTH,NONE
    # expande: YES/NO
    # anchor: N,E,S,W,CENTER
    # ipadx: x方向的內邊距
    # ipady: y
    # padx: x方向外邊界
    # pady: y........
    
    # pack佈局案例
    import tkinter
    baseFrame = tkinter.Tk()
    # 以下所有代碼都是創建一個組件,然後佈局
    btn1 = tkinter.Button(baseFrame, text='A')
    btn1.pack(side=tkinter.LEFT, expand=tkinter.YES, fill=tkinter.Y)
    btn2 = tkinter.Button(baseFrame, text='B')
    btn2.pack(side=tkinter.TOP, expand=tkinter.YES, fill=tkinter.BOTH)
    btn2 = tkinter.Button(baseFrame, text='C')
    btn2.pack(side=tkinter.RIGHT, expand=tkinter.YES, fill=tkinter.NONE, 
              anchor=tkinter.NE)
    btn2 = tkinter.Button(baseFrame, text='D')
    btn2.pack(side=tkinter.LEFT, expand=tkinter.NO, fill=tkinter.Y)
    btn2 = tkinter.Button(baseFrame, text='E')
    btn2.pack(side=tkinter.TOP, expand=tkinter.NO, fill=tkinter.BOTH)
    btn2 = tkinter.Button(baseFrame, text='F')
    btn2.pack(side=tkinter.BOTTOM, expand=tkinter.YES)
    btn2 = tkinter.Button(baseFrame, text='G')
    btn2.pack(anchor=tkinter.SE)
    baseFrame.mainloop()

#grid佈局
    #通用使用方式:組件對象.grid(設置,,,,,,,)
    #利用row,column編號,都是從0開始
    #sticky: N,E,S,W表示上下左右,用來決定組件從哪個方向開始
    #支持ipadx,padx等參數,跟pack函數含義一樣
    #支持rowspan,columnspan,表示跨行,跨列數量

    # grid佈局案例
    import tkinter
    baseFrame = tkinter.Tk()
    #下面被註釋掉的一行代碼跟下面兩行代碼等效
    #lb1 = tkinter.Label(baseFrame, text="賬號: ").grid(row=0, sticky= tkinter.W)
    lb1 = tkinter.Label(baseFrame, text="賬號: ")
    lb1.grid(row=0, sticky= tkinter.W)
    
    en = tkinter.Entry(baseFrame)
    en.grid(row=0, column=1, sticky=tkinter.E)
    
    lb2 = tkinter.Label(baseFrame, text="密碼: ").grid(row=1, sticky= tkinter.W)
    tkinter.Entry(baseFrame).grid(row=1, column=1, sticky=tkinter.E)
    btn = tkinter.Button(baseFrame, text="登錄").grid(row=2, column=1, sticky=tkinter.W)
    baseFrame.mainloop()
    
#place佈局
    #明確方位的擺放
    #相對位置佈局,隨意改變窗口大小會導致混亂
    #使用place函數,分爲絕對佈局和相對佈局,絕對佈局使用x,y參數
    #相對佈局使用relx,rely, relheight, relwidth
    
#==========================消息機制=====================
# 消息的傳遞機制
# 自動發出事件/消息
# 消息有系統負責發送到隊列
# 由相關組件進行綁定/設置
# 後端自動選擇感興趣的事件並做出相應反應
# 消息格式:
    #<[modifier-]---type-[-detail]>
    #: Button表示一個按鈕事件,1代表的是鼠標左鍵,2代表中鍵
    #: 鍵盤A鍵位
    #: 同時按下Control,Shift,A三個鍵位
    #:F1鍵盤
    #鍵位對應名稱
    
    # 消息的簡單例子:
    import tkinter

    def baseLabel(event):
            global  baseFrame
            print("哈哈,我被點擊了")
            lb = tkinter.Label(baseFrame, text="謝謝點擊")
            lb.pack()

    # 畫出程序的總框架
    baseFrame = tkinter.Tk()

    lb = tkinter.Label(baseFrame, text="模擬按鈕")
    # label綁定相應的消息和處理函數
    # 自動獲取左鍵點擊,並啓動相應的處理函數baseLabel
    lb.bind("<Button-1>", baseLabel)
    lb.pack()

    # 啓動消息循環
    # 到此,表示程序開始運行
    baseFrame.mainloop()
    
#Tkinter的綁定
    bind_all # 全局範圍的綁定,默認的是全局快捷鍵,比如F1是幫助文檔
    #bind_class 接受三個參數,第一個是類名,第二個是事件,第三個是操作
    w.bind_class("Entry", "", my_paste)
    bind # 單獨對某一個實例綁定
    unbind # 解綁,需要一個參數,即你要解綁哪個事件
    
#==========================Entry=========================
    #輸入框,功能單一
    entry["show"] = "*" # 設置遮擋字符
    
    # 輸入框案例
    import tkinter
    # 模擬的是登錄函數
    def reg():
        # 從相應輸入框中,得到用戶的輸入
        name = e1.get()
        pwd = e2.get()
        t1 = len(name)
        t2 = len(pwd)
        if name == "111" and pwd == "222":
            # 需要理解下面代碼的含義
            lb3["text"] = "登錄成功"
        else:
            lb3['text'] = "用戶名或密碼錯誤"
            # 輸入框刪除掉用戶輸入的內容
            # 注意delete的兩個參數,表示從第幾個刪除到第幾個
            e1.delete(0,t1)
            e2.delete(0,t2)
    # 啓動舞臺
    baseFrame = tkinter.Tk()

    lb1 = tkinter.Label(baseFrame, text="用戶名")
    lb1.grid(row=0, column=0, stick=tkinter.W )
    e1 = tkinter.Entry(baseFrame)
    e1.grid(row=0, column=1, stick=tkinter.E)
    lb2 = tkinter.Label(baseFrame, text="密碼: ")
    lb2.grid(row=1, column=0, stick=tkinter.W )
    e2 = tkinter.Entry(baseFrame)
    e2.grid(row=1, column=1, stick=tkinter.E)
    e2['show'] = '*'

    # Button參數command的意思是,當按鈕被點擊後啓動相應的處理函數
    btn = tkinter.Button(baseFrame, text="登錄", command=reg)
    btn.grid(row=2, column=1, stick=tkinter.E)
    lb3 = tkinter.Label(baseFrame, text="")
    lb3.grid(row = 3)

    # 啓動主Frame
    baseFrame.mainloop()
    
#==========================菜單=========================
# 1. 普通菜單
# 第一個Menu類定義的是parent
# add_command 添加菜單項,如果菜單是頂層菜單,則從左向右添加,否則就是下拉菜單
# label: 指定菜單項名稱
# command: 點擊後相應的調用函數
# acceletor: 快捷鍵
# underline: 制定是否菜單信息下有橫線
# menu:屬性制定使用哪一個作爲頂級菜單

    # 普通菜單的代碼
    import tkinter
    baseFrame = tkinter.Tk()
    menubar = tkinter.Menu(baseFrame)
    for item in ['File', 'Edit', 'View', 'About']:
        menubar.add_command(label=item)
    baseFrame['menu'] = menubar
    baseFrame.mainloop()
    
# 2、級聯菜單
# add_cascade:級聯菜單,作用是引出後面的菜單
# add_cascade的menu屬性:指明把菜單級聯到哪個菜單上
# label: 名稱
# 過程:
# 建立menu實例
# add_command
# add_cascade
    import tkinter
    baseFrame = tkinter.Tk()
    menubar = tkinter.Menu(baseFrame)
    emenu = tkinter.Menu(menubar)
    for item in ['Copy', 'Past', 'Cut']:
        emenu.add_command(label=item)
    menubar.add_cascade(label='File')
    menubar.add_cascade(label='Edit', menu=emenu)
    menubar.add_cascade(label='About')
    baseFrame['menu'] = menubar
    baseFrame.mainloop()
    
# 3、彈出式菜單
# 彈出菜單也叫上下文菜單
# 實現的大致思路
# 簡理財單並向菜單添加各種功能
# 監聽鼠標右鍵
# 如果右鍵點擊,則根據位置判斷彈出
# 調用Menu的pop方法
# add_separator: 添加分隔符

    import tkinter

    def makeLabel():
        global baseFrame
        tkinter.Label(baseFrame, text="PHP是最好的編程語言,我用Python").pack()
    baseFrame = tkinter.Tk()
    menubar = tkinter.Menu(baseFrame)
    for x in ['麻辣香菇', '氣鍋雞', '東坡肘子']:
        menubar.add_separator()
        menubar.add_command(label=x)
    menubar.add_command(label='重慶火鍋', command=makeLabel)
    # 事件處理函數一定要至少有一個參數,且第一個參數表示的是系統事件
    def pop(event):
        # 注意使用 event.x 和 event.x_root的區別 
        #menubar.post(event.x_root, event.y_root)
        menubar.post(event.x_root, event.y_root)
    baseFrame.bind("<Button-3>", pop)
    baseFrame.mainloop()

# 4、canvas 畫布
# 畫布: 可以自由的在上面繪製圖形的一個小舞臺
# 在畫布上繪製對象, 通常用create_xxxx,xxxx=對象類型, 例如line,rectangle
# 畫布的作用是把一定組件畫到畫布上顯示出來
# 畫布所支持的組件:
# arc
# bitmap
# image(BitmapImage, PhotoImage)
# line :畫線
# oval
# polygon :
# rectangle
# text
# winodw(組件)
# 每次調用create_xxx都會返回一個創建的組件的ID,同時也可以用tag屬性指定其標籤
# 通過調用canvas.move實現一個一次性動作

    import tkinter

    baseFrame = tkinter.Tk()
    def btnClick(event):
            global  w
            w.move(id_ball, 12,5)
            w.move("fall", 0,5)

    w = tkinter.Canvas(baseFrame, width=500, height=400)
    w.pack()
    w.bind("<Button-1>", btnClick)
    # 創建組件後返回id
    id_ball  = w.create_oval(20,20, 50,50, fill="green")
    # 創建組件使用tag屬性
    w.create_text(123,56, fill="red", text="ILovePython", tag="fall")
    # 創建的時候如果沒有指定tag可以利用addtag_withtag添加
    # 同類函數還有 addtag_all, addtag_above, addtag_xxx等等
    id_rectangle = w.create_rectangle(56,78,173,110, fill="gray")
    w.addtag_withtag("fall", id_rectangle)
    baseFrame.mainloop()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章