Python实战项目:文件内容搜索工具

流程

  • 创建控件
    • 关键字的标签和输入
    • 文件类型的标签和输入
    • 搜索按钮
    • 文件夹选择框
    • 列表框(滚动栏)
    • 子窗口
    • 文本框(滚动栏)
  • 点击搜索按钮,选择文件路径
  • 指定路径下过滤文件,文件插入到列表框
  • 双击文件,打开新的窗口,读取文件内容并插入到文本框中

练习模块tkinter

输入框

import tkinter as tk

# 登录界面
root = tk.Tk()
root.geometry("500x100")
username_label = tk.Label(root, text="用户名:")
username_label.pack(side=tk.LEFT)
username_entry = tk.Entry(root)
username_entry.pack(side=tk.LEFT)

passwd_label = tk.Label(root, text="密码:")
passwd_label.pack(side=tk.LEFT)
passwd_entry = tk.Entry(root, show="*")
passwd_entry.pack(side=tk.LEFT)

# print("用户名为:", username_entry.get())

def print_username():
    print("用户名为:", username_entry.get())
    username_entry.delete(0)
    username_entry.delete(0, 2)
    username_entry.delete(0, tk.END)

tk.Button(root, text="登录", command=print_username).pack(side=tk.LEFT, padx=20)

root.mainloop()

文本和列表框

import tkinter as tk


root = tk.Tk()
root.geometry("500x100")

text = tk.Text(root)
text.pack()
text.insert(tk.INSERT, "import tkinter as tk\n")
text.insert(tk.INSERT, "root = tk.Tk()\n")
text.insert(tk.END, "root.geometry(\"500x100\")\n")

print(text.get(0.0, 1.6))
print(text.get(0.0, tk.END))

# text.delete(0.0, tk.END)

# 插入控件
text.window_create(tk.INSERT, window=tk.Button(text, text="点一下"))

root.mainloop()
# -*- coding:utf-8 -*-
import tkinter as tk


root = tk.Tk()
root.geometry("300x200")
listbox1 = tk.Listbox(root)
listbox1.pack()
# listbox1.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# for item in range(20):
#     listbox1.insert(tk.END, item)

listbox1.insert(tk.END, *range(20))

sb1 = tk.Scrollbar(root, command=listbox1.yview)
sb1.pack()
# sb1.pack(side=tk.RIGHT, fill=tk.Y)
listbox1.config(yscrollcommand=sb1.set)

root.mainloop()

布局容器和子窗体

import tkinter as tk

root = tk.Tk()
root.geometry("200x100")

name_frame = tk.Frame(root)
name_frame.pack(anchor=tk.W, padx=10)
username_label = tk.Label(name_frame, text="用户名:")
username_label.pack(side=tk.LEFT)
username_entry = tk.Entry(name_frame)
username_entry.pack(side=tk.LEFT)


passwd_frame = tk.Frame(root)
passwd_frame.pack(anchor=tk.W, padx=10)
passwd_label = tk.Label(passwd_frame, text="密   码:")
passwd_label.pack(side=tk.LEFT)
passwd_entry = tk.Entry(passwd_frame, show="*")
passwd_entry.pack(side=tk.LEFT)

def create_window():
    top = tk.Toplevel()
    top.title("主页")
    top.geometry("800x600")
    tk.Label(top, text="欢迎访问主页", font=('宋体', 30)).pack()

tk.Button(root, text="登录", command=create_window).pack(side=tk.RIGHT, padx=10)

root.mainloop()

事件

import tkinter as tk

root = tk.Tk()
root.geometry("500x100")
label1 = tk.Label(root, text="来这里", font=('宋体', 30))
label1.pack()

def enter_text(event):
    label1.config(text="来了老弟")

def leave_text(event):
    label1.config(text="别走")

def key_text(event):
    label1.config(text=event.keysym)

label1.bind('<Enter>', enter_text)
label1.bind('<Leave>', leave_text)
label1.bind('<Key>', key_text)
label1.focus_set()  # 设置焦点才能接收键盘按键

root.mainloop()

对话框

import tkinter as tk
from tkinter import filedialog, colorchooser, messagebox

root = tk.Tk()
root.geometry("300x200")

def select_file():
    print(filedialog.askdirectory())
    # messagebox.askokcancel(message="确定使用该文件吗")
    # messagebox.showinfo(title="提醒", message="文件不存在")
    # print(filedialog.askopenfilename())

tk.Button(root, text="选择文件", command=select_file).pack()

def select_color():
    print(colorchooser.askcolor())

tk.Button(root, text="选择颜色", command=select_color).pack()

root.mainloop()

代码

主界面控件添加

root = tk.Tk()
root.title('everything')
root.geometry('600x300')
root.iconbitmap('../everything.ico')

# 输入框和搜索按钮
tk.Label(root, text='关键字:').pack()
key_entry = tk.Entry(root)
key_entry.pack()
tk.Label(root, text='文件类型:').pack()
type_entry = tk.Entry(root)
type_entry.pack()
search_button = tk.Button(root, text='搜索')
search_button.pack()

# 列表框
result_list_box = tk.Listbox(root)
result_list_box.pack(fill=tk.BOTH, expand=True)

root.mainloop()

主界面控件布局
 

# 搜索区域
search_frame = tk.Frame()
search_frame.pack()
# 输入框和搜索按钮
tk.Label(search_frame, text='关键字:').pack(side=tk.LEFT, padx=10, pady=10)
key_entry = tk.Entry(search_frame)
key_entry.pack(side=tk.LEFT, padx=10, pady=10)
tk.Label(search_frame, text='文件类型:').pack(side=tk.LEFT, padx=10, pady=10)
type_entry = tk.Entry(search_frame)
type_entry.pack(side=tk.LEFT, padx=10, pady=10)
search_button = tk.Button(search_frame, text='搜索')
search_button.pack(side=tk.LEFT, padx=10, pady=10)

# 列表框
result_list_box = tk.Listbox(root)
result_list_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
sb1 = tk.Scrollbar(root, command=result_list_box.yview)
sb1.pack(side=tk.RIGHT, fill=tk.Y)
result_list_box.config(yscrollcommand=sb1.set)

搜索功能

流程:

  • 获取用于搜索的数据:关键字、文件类型、文件路径
  • 遍历指定路径下的文件,进行过滤
  • 过滤过的文件插入到列表框
def search():
    print("点击搜索按钮")
    # 获取关键字、文件类型
    keyword = key_entry.get()
    if not keyword:
        messagebox.showinfo(title="温馨提示", message="请输入关键字")
        return
    file_type = type_entry.get()
    if not file_type:
        messagebox.showinfo(title="温馨提示", message="请输入文件类型")
        return
    print(f"输入的关键字为:{keyword}, 输入的文件类型为:{file_type}")

    # 通过文件对话框选择要搜索的路径
    filepath = filedialog.askdirectory()
    print("要搜索的路径为:", filepath)

    # 遍历该路径下的文件并过滤
    result_list_box.delete(0, tk.END)
    for dir_path, dir_names, filenames in os.walk(filepath):
        # 路径 目录名 文件名
        for filename in filenames:
            filename = os.path.join(dir_path.replace('/', '\\'), filename)
            # 后缀过滤
            if not filename.endswith(file_type):
                continue
            # 过滤关键字
            with open(filename, mode='r', encoding='utf-8-sig') as f:
                if keyword not in f.read():
                    continue
            # 文件插入到列表框里
            result_list_box.insert(tk.END, filename)

search_button.config(command=search)

搜索功能封装函数

search():

def search():
    print('点击搜索按钮')
    # 点击按钮获取输入的数据
    res = get_search_data()
    if not res:
        return
    keyword, file_type = res

    # 通过文件对话框选择要搜索的路径
    filepath = filedialog.askdirectory()
    print('要搜索的路径为:', filepath)

    # 获取文件并过滤
    files = filter_files(get_files(filepath), file_type, keyword)

    # 文件名填入列表框
    result_list_box.delete(0, tk.END)
    for file in files:
        result_list_box.insert(tk.END, file)

get_search_data():

def get_search_data():
    keyword = key_entry.get()
    if not keyword:
        messagebox.showinfo(message='请输入关键字')
        return
    file_type = type_entry.get()
    if not file_type:
        messagebox.showinfo(message='请输入文件类型')
        return
    return keyword, file_type

get_files():

def get_files(filepath):
    files = []
    for dir_path, dir_names, filenames in os.walk(filepath):
        # 路径 目录名 文件名
        for filename in filenames:
            files.append(os.path.join(dir_path.replace('/', '\\'), filename))
    return files

filter_files():

def filter_files(files, file_type=None, keyword=None):
    print("文件过滤中。。。")
    new_files = []
    for file in files:
        if file_type and not file.endswith(file_type):
            continue
        if keyword:
            with open(file, mode='r', encoding='utf-8-sig') as f:
                if keyword not in f.read():
                    continue
        new_files.append(file)
    return new_files

文件内容展示功能

流程:

  • 绑定事件到列表框
  • 获取被选中的文件路径
  • 创建一个子窗口
  • 创建文本框及滚动栏
  • 文件内容插入到文本框
def create_scrollbar(master, target):
    sb = tk.Scrollbar(master, command=target.yview)
    sb.pack(side=tk.RIGHT, fill=tk.Y)
    target.config(yscrollcommand=sb.set)


def click_file(event):
    print("点击选择文件")

    # 获取列表框中被选中的路径
    file_path = result_list_box.get(result_list_box.curselection()[0])
    print("选择的文件路径为:", file_path)

    # 创建子窗口
    top = tk.Toplevel()
    top.title("查看内容")
    top.iconbitmap('../everything.ico')

    # 创建文本框及滚动栏
    file_text = tk.Text(top)
    file_text.pack(side=tk.LEFT)
    create_scrollbar(top, file_text)

    # 文件内容插入文本框
    with open(file_path, mode='r', encoding='utf-8') as f:
        content = f.read()
        file_text.insert(tk.END, content)


result_list_box.bind('<Double-Button-1>', click_file)

面向对象封装

main.py

from app import Application


def main():
    print("文件内容搜索工具开始运行")
    app = Application()
    app.mainloop()


if __name__ == '__main__':
    main()

app.py

import tkinter as tk
from tkinter import messagebox, filedialog
from utils import get_files, filter_files, create_scrollbar
from config import *


class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        # 窗口配置
        self.title(APP_TITLE)
        self.geometry(APP_SIZE)
        self.iconbitmap(APP_ICON_PATH)

        # 创建控件
        self.search_frame = SearchFrame()
        self.result_list_box = ResultListBox(self, width=80)
        create_scrollbar(self, self.result_list_box)

        # 绑定函数
        self.search_frame.button_config_search(self.result_list_box)
        self.result_list_box.bind_double_click()


class SearchFrame(tk.Frame):
    def __init__(self):
        super().__init__()
        self.pack(side=tk.TOP)

        # 关键字的标签和输入
        tk.Label(self, text='关键字:').pack(LABEL_PACK)
        self.key_entry = tk.Entry(self)
        self.key_entry.pack(LABEL_PACK)

        # 文件类型的标签和输入
        tk.Label(self, text='文件类型:').pack(LABEL_PACK)
        self.type_entry = tk.Entry(self)
        self.type_entry.pack(LABEL_PACK)

        # 搜索按钮
        self.search_button = tk.Button(self, text='搜索')
        self.search_button.pack(LABEL_PACK)

    def button_config_search(self, result_list_box):
        self.search_button.config(command=self.search(result_list_box))

    def get_search_data(self):
        print("获取搜索数据中。。。")
        keyword = self.key_entry.get()
        if not keyword:
            messagebox.showinfo(message='请输入关键字')
            print("请输入关键字")
            return
        file_type = self.type_entry.get()
        if not file_type:
            messagebox.showinfo(message='请输入文件类型')
            print("请输入文件类型")
            return
        print(f'搜索关键字: {keyword},文件类型:{file_type}')
        return keyword, file_type

    def search(self, result_list_box):
        def func():
            print('点击搜索按钮')
            # 点击按钮获取输入的数据
            res = self.get_search_data()
            if not res:
                return
            keyword, file_type = res

            # 通过文件对话框选择要搜索的路径
            filepath = filedialog.askdirectory()
            print('要搜索的路径为:', filepath)

            # 获取文件并过滤
            files = get_files(filepath)
            files = filter_files(files, file_type, keyword)

            # 文件名填入列表框
            result_list_box.delete(0, tk.END)
            for file in files:
                result_list_box.insert(tk.END, file)
        return func


class ViewWindow(tk.Toplevel):
    def __init__(self):
        super().__init__()
        self.title("查看内容")
        self.iconbitmap('../everything.ico')
        self.file_text = tk.Text(self)
        self.file_text.pack(side=tk.LEFT)
        create_scrollbar(self, self.file_text)


    def insert_file(self, file_path):
        print("读取文件内容,并插入到文本框")
        with open(file_path, mode='r', encoding='utf-8 ') as f:
            content = f.read()
            self.file_text.insert(tk.END, content)
        print("插入完毕")


class ResultListBox(tk.Listbox):
    def __init__(self, master=None, cnf={}, **kw):
        super().__init__(master=master, cnf=cnf, **kw)
        self.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    def bind_double_click(self):
        self.bind('<Double-Button-1>', self.click_file)

    def click_file(self, event):
        print('点击选择文件')
        # 获取列表框被选中的文件路径
        file_path = self.get(self.curselection()[0])
        print('选择的文件路径为:', file_path)

        # 新的窗口展示文件内容
        ViewWindow().insert_file(file_path)

utils.py

import os
import tkinter as tk


def get_files(filepath):
    files = []
    for dir_path, dir_names, filenames in os.walk(filepath):
        # 路径 目录名 文件名
        for filename in filenames:
            files.append(os.path.join(dir_path.replace('/', '\\'), filename))
    return files


def create_scrollbar(master, target):
    sb = tk.Scrollbar(master, command=target.yview)
    sb.pack(side=tk.RIGHT, fill=tk.Y)
    target.config(yscrollcommand=sb.set)


def filter_files(files, file_type=None, keyword=None):
    print("文件过滤中。。。")
    new_files = []
    for file in files:
        if file_type and not file.endswith(file_type):
            continue
        if keyword:
            with open(file, mode='r', encoding='utf-8-sig') as f:
                if keyword not in f.read():
                    continue
        new_files.append(file)
    return new_files

config.py

APP_TITLE = "文件内容搜索工具"
APP_SIZE = "600x300"
APP_ICON_PATH = "../everything.ico"

VIEW_WINDOW_TITLE = "查看内容"
VIEW_WINDOW_ICON_PATH = "../everything.ico"

LABEL_PACK = {
    "side": "left",
    "padx": 10,
    "pady": 10
}

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值