一、概述
二、布局管理
三、常用组件
四、实战(一)
五、实战(二)
六、进阶 自定义控件
推荐视频课程 tkinter从入门到实战
经过前几篇的基础学习,这一篇将综合运用组件,实战开发一个小工具,我们这个小工具是有一定实用意义的,不是假装写一个简单的登录窗口就完事了那种。
不知大家工作中使用过一个叫everything的工具没有,这是一个相当好用的工具,功能还挺多,没用过的话我就推荐一下,有哪些功能可以自行探索,我主要使用文件搜索功能,可以模糊搜索文件名,秒搜出路径,当你不记得曾下载的文件放哪去了的时候,你绝对需要这款神器,没错windows上的神器。我通常将everything搭配另一款windows神器FileLocator Pro 一起使用,这真的是用windows系统的程序员神器,FileLocator Pro是用来快速搜索文本文件内容的,一个搜索文件名另一个搜索文件内容,搭配使用,我感觉比source insight要好用一点,因为我工作电脑上通常有将近十套Android源码,不同芯片厂商和不同版本,一套源码多大,几十个G,用source insight必须要创建索引,建立数据库,对于我来说太过于笨重了,扯远了,总之就是everything + FileLocator Pro 源码跟踪神器,那么我们今天就用tkinter模仿做一个超简单版everything 。
上代码之前,先说一点,我这里使用了一点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项目,肯定是使用面向对象的思维,这里在构造方法中做了一些初始化,以及根窗体属性的设置。并通过两个方法来创建主要界面
如上图,最外层是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线程与异步线程的交互