python GUI编程


摘要:本章,我们来学习python的图形界面编程。在python中,默认的图形界面是Tkinter(interface)——注意,k是小写的。


1.编程环境与运行原理

如果你使用的是python3.0以前的版本,默认是没有安装图形界面的。你需要使用yum或者apt来安装tkinter,它是python的默认GUI库,基于Tk工具集,最初是为工具命令语言(Tcl)设计的。
GUI编程是一种C/S架构,没法脱离窗口系统,其中窗口是服务器,我们的GUI是客户机。

创建并运行GUI的过程如下:
1)导入Tkinter模块
2)创建顶层串口对象top(名字不限),容纳整个GUI程序
3)在top上创建其他模块
4)将这些GUI模块与底层代码关联
5)进入主循环事件

Tkinter.Tk()返回的窗口是根窗口,一般命名是root或者top。我们可以创建多个顶层窗口(其他所有的组件都放在这个窗口之中),但是只有一个root。
组件既可以是独立的,也可以作为容器存在,作为容器的时候,他就是容器中组件的父组件。
组件会有一定的行为和动作:按钮被按下、进度条被拖动、文本框被写入,这些用户行为是“事件”,针对事件的相应动作称为“回调函数”(callback)。用户操作,产生事件,然后相应的callback执行,整个过程被称为事件驱动,很显然,我们需要定义callback函数。
界面编程的工作主要有三个:组件的创建与布局,组件间动作的关联,回调函数的处理

2.Tk组件


2.1顶层窗口

import Tkinter
top=Tkinter.Tk()

2.2其他组件

目前Tk共有15种组件:
Button:按钮,类似标签,提供额外的功能:鼠标掠过、按下、释放、键盘操作
Canvas:画布,提供绘图功能
checkbutton:选择按钮,可以选择任意个
Entry:文本框
Frame:框架,包含其他组件的纯容器
label:注意,不是lable
listbox:列表框
menu:菜单
menubutton:菜单按钮
message:消息框,可以显示多行文本
radiobuttonscale:单选按钮
scrollbar:滚动条——对其支持的组件(文本框、画布、列表框、文本区域)提供滚动功能
text:文本区域
scale:进度条
toplevel:顶级,类似框架,提供一个单独的容器。

对GUI编程的学习,一个很重要的方面就是各个控件的学习,包括属性,常用方法等。

3.一个GUI程序的设计和实施实例

3.1功能设计:

我们设计一个这样的程序,给定目录,能够显示目录下的文件;

双击目录,能够显示这个目录下的文件;
可以通过滚动条,查看不再视觉区域内部的文件;

3.2界面设计:

\

3.3逻辑设计:

1)事件设计
点击clear:清楚listbox中的所有内容
点击quit:退出
点击list:列出选中的目录下的内容;如果没有选中目录,不进行处理;如果选中的是文件,不进行任何处理
在文本框中输入路径:判断路径是否合法;如果是目录,list it
双击listbox中的文件或者文件夹:列出目录下的内容
拖动滚动条:显示listbox下的文件

2)回调函数的定义
clrdir():clear listbox
doLs():list the given dir

3.4相关代码

#!/usr/bin/env python
# encoding: utf-8
import os
from time import sleep
from Tkinter import *

class DirList(object):


	def __init__(self,initdir=None):
		""" """
		self.top=Tk()
		self.title_label=Label(self.top,text="Directory Lister V1.1")
		self.title_label.pack()

		self.cwd=StringVar(self.top)

		self.cwd_lable=Label(self.top,fg='blue',font=('Helvetica',12,'bold'))
		self.cwd_lable.pack()

		self.dirs_frame=Frame(self.top)
		
		self.sbar=Scrollbar(self.dirs_frame)
		self.sbar.pack(side=RIGHT,fill=Y)
		
		self.dirs_listbox=Listbox(self.dirs_frame,height=15,width=50,yscrollcommand=self.sbar.set)
		self.dirs_listbox.bind('',self.setDirAndGo)
		self.dirs_listbox.pack(side=LEFT,fill=BOTH)
		
		self.dirs_frame.pack()
				
		self.dirn=Entry(self.top,width=50,textvariable=self.cwd)
		self.dirn.bind("",self.doLS)
		self.dirn.pack()

		self.bottom_frame=Frame(self.top)
		self.clr=Button(self.bottom_frame,text="Clear",command=self.clrDir,activeforeground='white',activebackground='blue')
		self.ls=Button(self.bottom_frame,text="LS",command=self.doLS,activeforeground='white',activebackground='blue')
		self.quit=Button(self.bottom_frame,text="Quit",command=self.top.quit,activeforeground='white',activebackground='blue')
		self.clr.pack(side=LEFT)
		self.ls.pack(side=LEFT)
		self.quit.pack(side=LEFT)
		self.bottom_frame.pack()

		if initdir:
			self.cwd.set(os.curdir)
			self.doLS()
	
	def clrDir(self,ev=None):
		#self.cwd.set('')
		self.dirs_listbox.delete(first=0,last=END)


	def setDirAndGo(self, ev=None):
		"""pass


		:ev: @todo
		:returns: @todo


		"""
		self.last=self.cwd.get()
		self.dirs_listbox.config(selectbackground='red')
		check=self.dirs_listbox.get(self.dirs_listbox.curselection())
		if not check:
				check=os.curdir
		#check is the selected item for file or directory
		self.cwd.set(check)
		self.doLS()
	
	def doLS(self,ev=None):
		error=""
		self.cwd_lable.config(text=self.cwd.get())
		tdir=self.cwd.get()#get the current working directory
		if not tdir:
			tdir=os.curdir


		if not os.path.exists(tdir):
			error=tdir+':no such file'
		elif not os.path.isdir(tdir):
			error=tdir+":not a directory"


		if error:#if error occured
			self.cwd.get(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_listbox.config(selectbackground='LightSkyBlue')
				self.top.update()
				return
		self.cwd.set("fetching dir contents")
		self.top.update()
		dirlist=os.listdir(tdir)
		dirlist.sort()
		os.chdir(tdir)
		self.dirs_listbox.delete(0,END)
		self.dirs_listbox.insert(END,os.curdir)
		self.dirs_listbox.insert(END,os.pardir)
		for eachfile in dirlist:
			self.dirs_listbox.insert(END,eachfile)
		self.cwd.set(os.curdir)
		self.dirs_listbox.config(selectbackground='LightSkyBlue')
	
		
def main():
	d=DirList(os.curdir)
	mainloop()

if __name__ == '__main__':
	main()


评论关闭