《GUI编程》第五章 (续)

本文介绍两个Tkinter的应用案例,一是使用偏函数简化按钮创建过程,二是实现一个目录列表程序,展示如何利用Tkinter构建GUI应用。

2018-6-14

5.3.5 偏函数应用示例

from functools import partial as pto
from tkinter import Tk, Button, X
#from tkinter import messagebox
from tkinter.messagebox import showinfo, showwarning, showerror

WARN = 'warn'
CRIT = 'crit'
REGU = 'regu'

SIGN = {
        'do not enter': CRIT,
        'railroad crossing': WARN,
        '55\nspeed limit': REGU,
        'wrong way': CRIT,
        'merging traffic': WARN,
        'one way': REGU
        }

critCB = lambda: showerror('ERROR', 'Error Button Pressed!')
warnCB = lambda: showwarning('Warning', 'Warning Button Pressed!')
infoCB = lambda: showinfo('Info', 'Info Button Pressed!')

top = Tk()
top.title('Road Signs')
Button(top, text='Quit',command=top.quit,bg='red',fg='white').pack()

MYBotton = pto(Button, top) #偏函数(固定top参数,其他参数可变,与Button相似)
CritButton = pto(MYBotton,command=critCB,bg='white', fg='red')
WarnButton = pto(MYBotton,command=warnCB,bg='goldenrod1')
ReguButton = pto(MYBotton,command =infoCB,bg='white')


for eachSign in SIGN:
    signtype = SIGN[eachSign]
    cmd = '%sButton(text=%r%s).pack(fill=X,expand=True)' \
                   %(signtype.title(), eachSign,'.upper()' if signtype==CRIT else '.title()')
    eval(cmd)

top.mainloop()


**********************************************************************************************************

部分代码注释:

1、由于使用python3.6 所以,以前2.5版本的tkMessageBox的导入改为:

from tkinter.messagebox import showinfo, showwarning, showerror

2、偏函数使用MYButton=pto(Button,top)将Button(top,...)中的top参数固定下来,同时不影响其他参数的配置。

3、cmd语句中,格式化输出%r和%s分别表示将所有内容转换成字符串和将内容以字符串形式输出。%r在打印时能够重现其代表的对象:


4、eval(cmd)命令:实现了字符串向list,dict,tuple三种类型的转换,而str()函数刚好相反:实现其他三种类型数据向字符串的转换。

5.3.6 中级tkinter实例

listdir()的复现。

from time import sleep
import os
from tkinter import *


class Dirlist(object):
    def __init__(self, initdir=None):
        self.top = Tk()
        self.label = Label(self.top,text='Directory Lister v1.1')

        self.label.pack()   # 创建第一个Label控件

        
        self.cwd=StringVar(self.top)  # 声明cwd变量,保存当前所在目录名
        
        self.dirl = Label(self.top, fg='blue',font=('Helvetica',12,'bold'))
        self.dirl.pack()  # 创建了另一个Label控件

        

        # 定义了GUI应用的核心部分Listbox控件dirs,该空间包含了要列出的目录的文件列表。Scrollbar可以让用户在文件数超过Listbox大小时能够移动列表。上诉两个控件都包含在Frame控件中,通过使用Listbox的bind方法,Listbox的列表项可以与回调函数setDirAndGo连接起来。

        self.dirfm = Frame(self.top)
        self.dirsb = Scrollbar(self.dirfm)
        self.dirsb.pack(side=RIGHT, fill=Y)
        self.dirs= Listbox(self.dirfm, height=15, width=50, \
                           yscrollcommand=self.dirsb.set)
        self.dirs.bind('<Double-1>',self.setDirAndGo)
        self.dirsb.config(command=self.dirs.yview)
        self.dirs.pack(side=LEFT,fill=BOTH)
        self.dirfm.pack()
        # 创建了一个文本框,并增加了回车键的绑定,同时,双击条目也可以进行更新文件列表
        self.dirn = Entry(self.top, width = 50,textvariable=self.cwd)
        self.dirn.bind('<Return>',self.doLS)
        self.dirn.pack()
        # 定义了一个按钮的框架,放置三个按钮(clear,ls,quit),每个按钮按下时都有自己的配置和回调函数
        self.bfm = Frame(self.top)
        self.clr = Button(self.bfm, text='Clear',
                          command=self.clrDir,
                          activeforeground='white',
                          activebackground='blue')
        self.ls = Button(self.bfm,
                         text='List Directory',
                         command=self.doLS,
                         activeforeground='white',
                         activebackground='blue')
        self.quit = Button(self.bfm,
                         text='Quit',
                         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()
        # 构造函数的最后一步分初始化程序,并以当前工作目录作为起始点。
        if initdir:
            self.cwd.set(os.curdir)
            self.doLS()

    #clrDir方法可以清空Tk字符串变量cwd(包括当前活动目录)。当发生错误时可以帮助我们回到之前的目录。

回调函数中变量ev的默认值是None,任何像这样的值都是由窗口系统传入的。

    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):
            errortdir+': no such file'
        elif not os.path.isdir(tdir):
            error = tdir + ': not a directory'
            
        if error:
            self.cwd.set(error)
            self.top.update()
            sleep(2)
            if not (hasattr(self, 'last')\
                    and self.last):
                self.last = os.curdor
            self.cwd.set(self.last)
            self.dirs.config(selectbackground='LightSkyBlue')
            self.top.update()
            return
        
        self.cwd.set(\
                     'FETCHING DIRECTORY CONTENTS...')
        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:
            self.dirs.insert(END, eachFile)
        self.cwd.set(os.curdir)
        self.dirs.config(\
                         selectbackground='LightSkyBlue')
        
def main():
    d = Dirlist(os.curdir)
    mainloop()
        
if __name__=='__main__':
    main()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值