python GUI編程tkinter示例之目錄樹遍歷工具


摘錄 python核心編程

本節我們將展示一個中級的tkinter應用實例,這個應用是一個目錄樹遍歷工具:它會從當前目錄開始,提供一個文件列表,雙擊列表中任意的其他目錄,就會使得工具切換到新目錄中,用新目錄中的文件列表代替舊文件列表。這里新增了列表框、文本框和滾動條,此外還增加了鼠標單擊、鍵盤按下、滾動操作等回調函數。其實,整個應用就是一系列控件和函數的組合。

 

#python 3.6

import os
from time import sleep
from tkinter import *

#一個生成GUI應用的自定義類
class DirList(object):
    #構造函數
    def __init__(self,initdir=None):
        self.top = Tk()#頂層窗口
        self.label = Label(self.top,text = '查找文件工具V1.0')#第一個標簽控件
        self.label.pack()
        '''
        StringVar,並不是Python內置的數據類型,而是tkinter模塊內的對象。
        我們在使用GUI界面編程時,有時候需要跟蹤變量的值的變化,以保證值的變化隨時可以顯示在界面上。而Python無法做到這一點。這里采用了Tcl工具中對象。
        StringVar 、BooleanVar、DoubleVar、IntVar都屬於這類情況
        StringVar()保存了一個string類型變量,默認值是''
        get()方法可以得到保存的值
        set()方法設置/更改保存的值
        Variable類,有些控件如Entry(本例中出現)、Radiobutton,可以通過傳入特定參數直接和一個程序變量綁定,這些參數包括:variable、textvariable、onvalue、offvalue、value
        這種綁定是雙向的:如果該變量發生改變,於該變量綁定的控件也會隨之更新。
        '''
        self.cwd = StringVar(self.top)
        #第二個標簽控件。用於動態展示一些文本信息
        self.dirl = Label(self.top,fg = 'blue',font = ('Helvetica',12,'bold'))
        self.dirl.pack()
        
        self.dirfm = Frame(self.top)#第一個Frame控件,一個包含其他控件的純容器
        self.dirsb = Scrollbar(self.dirfm)#主要是提供滾動功能
        self.dirsb.pack(side = RIGHT,fill = Y)#滾動條靠右填充整個剩余空間
        '''
        一個選項列表,指定列表yscrollbar的回調函數為滾動條的set,同時滾動條的command回調的是列表的yview
        可以這么理解二者的關系:當Listbox改變時(比如使用向上、向下方向鍵改變列表內容時),滾動條調用set方法改變滑塊的位置;
        當滾動條的滑塊位置發生變化時,列表將調用yview以展示新的項。
        同學們可以將綁定取消,自行觀察現象。
        '''
        self.dirs = Listbox(self.dirfm,height = 15,width = 50,yscrollcommand = self.dirsb.set)
        #綁定操作。這意味着將一個回調函數與按鍵、鼠標操作或者其他的一些事件連接起來。這里當雙擊任意條目時,會調用setDirAndGo函數
        self.dirs.bind('<Double-1>',self.setDirAndGo)
        self.dirsb.config(command=self.dirs.yview)#這里同列表控件的yscrollcommand回調結合起來
        self.dirs.pack(side = LEFT,fill = BOTH)
        self.dirfm.pack()
        
        self.dirn = Entry(self.top,width = 50,textvariable = self.cwd)#單行文本框。指定了寬度;同時設置了一個可變類型參數textvariable的值
        self.dirn.bind('<Return>',self.doLS)#綁定操作。這里當敲擊回車鍵時,調用函數doLS
        self.dirn.pack()
        
        self.bfm = Frame(self.top)#第二個Frame控件
        #定義了三個按鈕,每個按鈕分別回調不同的函數,並設置了激活前景色、激活后景色
        self.clr = Button(self.bfm,text = '清空',command = self.clrDir,activeforeground = 'white',activebackground = 'blue')
        self.ls = Button(self.bfm,text = '搜索目錄',command = self.doLS,activeforeground = 'white',activebackground = 'green')
        self.quit = Button(self.bfm,text = '退出',command = self.top.quit,activeforeground = 'white',activebackground = 'red')
        
        self.clr.pack(side = LEFT)
        self.ls.pack(side = LEFT)
        self.quit.pack(side = LEFT)
        self.bfm.pack()
        
        #構造函數最后一部分,用於初始化GUI程序,以當前工作目錄作為起始點。
        if initdir:
            self.cwd.set(os.curdir)
            self.doLS()
    #清空函數,用於清空cwd,包含當前活動目錄       
    def clrDir(self,ev = None):    
        self.cwd.set('')
    
    #設置要遍歷的目錄;最后又調用doLS函數
    def setDirAndGo(self,ev = None):
        self.last = self.cwd.get()
        self.dirs.config(selectbackground = 'red')
        check = self.dirs.get(self.dirs.curselection())
        if not check:
            check = os.curdir
        self.cwd.set(check)
        self.doLS()
    
    #實現遍歷目錄的功能,這也是整個GUI程序最關鍵的部分。
    def doLS(self,ev = None):
        error = ''
        tdir = self.cwd.get()
        #進行一些安全檢查
        if not tdir:
            tdir = os.curdir
        if not os.path.exists(tdir):
            error = tdir + ': 沒有這個文件'
        elif not os.path.isdir(tdir):
            error = tdir + ':不是文件夾'
        #如果發生錯誤,之前的目錄就會重設為當前目錄    
        if error:
            self.cwd.set(error)
            self.top.update()
            sleep(2)
            if not (hasattr(self,'last') and self.last):
                self.last = os.curdir
            self.cwd.set(self.last)
            self.dirs.config(selectbackground = 'LightSkyBlue')
            self.top.update()
            return
        #如果一切正常    
        self.cwd.set('正在獲取目標文件夾內容……')
        self.top.update()
        dirlist = os.listdir(tdir)#獲取實際文件列表
        dirlist.sort()
        os.chdir(tdir)
        
        self.dirl.config(text = os.getcwd())
        self.dirs.delete(0,END)
        self.dirs.insert(END,os.curdir)
        self.dirs.insert(END,os.pardir)
        for eachFile in dirlist:#替換Listbox中的內容
            self.dirs.insert(END,eachFile)
        self.cwd.set(os.curdir)
        self.dirs.config(selectbackground = 'LightSkyBlue')
#主函數,應用程序入口。main函數會創建一個GUI應用,,然后調用mainloop函數來啟動GUI程序
def main():
    d = DirList(os.curdir)
    mainloop()
    
if __name__ == '__main__':
    main()

運行效果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM