Python GUI之tkinter 實戰(一)

Python3 tkinter系列

一、概述
二、佈局管理
三、常用組件
四、實戰(一)
五、實戰(二)

經過前幾篇的基礎學習,這一篇將綜合運用組件,實戰開發一個小工具,我們這個小工具是有一定實用意義的,不是假裝寫一個簡單的登錄窗口就完事了那種。

不知大家工作中使用過一個叫everything的工具沒有,這是一個相當好用的工具,功能還挺多,沒用過的話我就推薦一下,有哪些功能可以自行探索,我主要使用文件搜索功能,可以模糊搜索文件名,秒搜出路徑,當你不記得曾下載的文件放哪去了的時候,你絕對需要這款神器,沒錯windows上的神器。我通常將everything搭配另一款windows神器FileLocator Pro 一起使用,這真的是用windows系統的程序員神器,FileLocator Pro是用來快速搜索文本文件內容的,一個搜索文件名另一個搜索文件內容,搭配使用,我感覺比source insight要好用一點,因爲我工作電腦上通常有將近十套Android源碼,不同芯片廠商和不同版本,一套源碼多大,幾十個G,用source insight必須要創建索引,建立數據庫,對於我來說太過於笨重了,扯遠了,總之就是everything + FileLocator Pro 源碼跟蹤神器,那麼我們今天就用tkinter模仿做一個超簡單版everything 。

everything界面:
這裏寫圖片描述

上我們tkinter的界面:
這裏寫圖片描述

上代碼之前,先說一點,我這裏使用了一點ttk,什麼是ttk?其實我覺得可以理解爲對控件的一個美化。因爲一些原因,tkinter做出的界面感年代久遠,於是出現了這麼一個ttk的東西,讓界面風格可以更接近當前的系統平臺,相當於稍稍美化一下,實際上與之前博客講的控件使用沒有什麼區別,只是多導一個包

from tkinter import *
from tkinter import ttk
import tkinter.filedialog as dir

class AppUI():

    def __init__(self):
        root = Tk()
        self.create_menu(root)
        self.create_content(root)
        self.path = 'C:'
        root.title("磁盤文件搜索工具")
        root.update()
        # root.resizable(False, False) 調用方法會禁止根窗體改變大小
        #以下方法用來計算並設置窗體顯示時,在屏幕中心居中
        curWidth = root.winfo_width()  # get current width
        curHeight = root.winfo_height()  # get current height
        scnWidth, scnHeight = root.maxsize()  # get screen width and height
        tmpcnf = '+%d+%d' % ((scnWidth - curWidth) / 2, (scnHeight - curHeight) / 2)
        root.geometry(tmpcnf)
        root.mainloop()


    def create_menu(self,root):
        #創建菜單欄
        menu = Menu(root)

        #創建二級菜單
        file_menu = Menu(menu,tearoff=0)
        file_menu.add_command(label="設置路徑",command=self.open_dir)
        file_menu.add_separator()

        scan_menu = Menu(menu)
        file_menu.add_command(label="掃描")

        about_menu = Menu(menu,tearoff=0)
        about_menu.add_command(label="version:1.0")

        #在菜單欄中添加以下一級菜單
        menu.add_cascade(label="文件",menu=file_menu)
        menu.add_cascade(label="關於",menu=about_menu)
        root['menu'] = menu

    def create_content(self, root):
        lf = ttk.LabelFrame(root, text="文件搜索")
        lf.pack(fill=X, padx=15, pady=8)

        top_frame = Frame(lf)
        top_frame.pack(fill=X,expand=YES,side=TOP,padx=15,pady=8)

        self.search_key = StringVar()
        ttk.Entry(top_frame, textvariable=self.search_key,width=50).pack(fill=X,expand=YES,side=LEFT)
        ttk.Button(top_frame,text="搜索",command=self.search_file).pack(padx=15,fill=X,expand=YES)

        bottom_frame = Frame(lf)
        bottom_frame.pack(fill=BOTH,expand=YES,side=TOP,padx=15,pady=8)

        band = Frame(bottom_frame)
        band.pack(fill=BOTH,expand=YES,side=TOP)

        self.list_val = StringVar()
        listbox = Listbox(band,listvariable=self.list_val,height=18)
        listbox.pack(side=LEFT,fill=X,expand=YES)

        vertical_bar = ttk.Scrollbar(band,orient=VERTICAL,command=listbox.yview)
        vertical_bar.pack(side=RIGHT,fill=Y)
        listbox['yscrollcommand'] = vertical_bar.set

        horizontal_bar = ttk.Scrollbar(bottom_frame,orient=HORIZONTAL,command=listbox.xview)
        horizontal_bar.pack(side=BOTTOM,fill=X)
        listbox['xscrollcommand'] = horizontal_bar.set

        #給list動態設置數據,set方法傳入一個元組,注意此處是設置,不是插入數據,此方法調用後,list之前的數據會被清除
        self.list_val.set(('jioj',124,"fjoweghpw",1,2,3,4,5,6))

    def search_file(self):
        pass

    def open_dir(self):
        d = dir.Directory()
        self.path = d.show(initialdir=self.path)



if __name__ == "__main__":
    AppUI()

首先創建一個AppUI類,類似的GUI項目,肯定是使用面向對象的思維,這裏在構造方法中做了一些初始化,以及根窗體屬性的設置。並通過兩個方法來創建主要界面

  • create_menu方法
    該方法主要處理菜單欄菜單的創建,菜單作爲一個控件,與上一篇博客常用控件中講的控件也大同小異,詳細屬性的使用,可查閱官方文檔

這裏給一個官方示例
這裏寫圖片描述

  • create_content方法
    該方法包含了主要內容的創建。此處主要使用pack佈局,之所以使用pack佈局,正好接續之前博客講到的分層佈局思想。實際上,通過分層,複雜的佈局pack一樣能實現,而不是網絡上一些博客流傳的錯誤,只能使用grid佈局。pack佈局的優勢就是簡潔單一,且能實現一些填充效果,比如說當窗體可以拉伸改變大小時,pack的效果要比grid好,如本例,但是正由於簡潔單一,某些複雜佈局就只能通過分層來組合實現。

這裏寫圖片描述

如上圖,最外層是ttk中的LabelFrame,這個控件是一個帶邊框效果的Frame,其次是top_frame,它用來盛放單行文本框與搜索按鈕,緊接其下的是bottom_frame,它用來盛放搜索的列表框,在bottom_frame中又添加了一層band,它是直接用來放Listbox控件與垂直方向的Scrollbar,即一個滾動條,這裏爲什麼要加一層band呢?因爲pack佈局的簡單性,它無法用來將Listbox與橫縱兩個方向的滾動條組合起來,它一次只能組合一個。

實際上組合橫縱兩個滾動條可以使用grid佈局,但是對於根窗體可自由拉伸時的支持效果感覺不太好,且此處也是着重用來講解分層佈局,所以未使用,但此處仍然給出一個官方示例
這裏寫圖片描述
此示例與組合橫縱兩個滾動條稍有出入,但其實將位於底部的Sizegrip組件換成水平方向Scrollbar就行

關於Listbox與Scrollbar的簡單使用,可查看官方文檔的示例( Python GUI之tkinter 常用組件這篇博客已經給出官方文檔下載路徑,不再贅述),最後簡述一下關於打開文件夾對話框的問題

Python2.x版本中使用的tkFileDialog 在Python3.x版本已經不能使用,替代的是tkinter.filedialog,該模塊封裝了一些文件對話框的操作,但是此次我並沒有使用filedialog的askdirectory函數來打開一個文件夾選擇對話框,原因是該封裝過於死板,無法實現一個小功能,即上次打開一個文件夾路徑,希望能記住這個路徑,下次打開仍是這個路徑。

askdirectory使用如下:

import tkinter.filedialog as dir
#initialdir 屬性爲傳入默認打開的路徑
path = dir.askdirectory(initialdir=r"C:\Windows")

我工程使用的方式通過Directory類實現,每次打開時傳入一個默認路徑

def open_dir(self):
        d = dir.Directory()
        self.path = d.show(initialdir=self.path)

好了,界面的部分先到這裏,下一篇博客着重於功能的實現,以及UI線程與異步線程的交互

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