使用 Tkinter 构建一个文本分割工具

使用 Tkinter 构建一个文本分割工具

在日常的编程工作中,我们有时会遇到需要将大段文本按照一定规则分割成小段的情况。手动完成这项任务既耗时又容易出错,因此编写一个小工具来自动处理这种需求是非常有用的。本博文将介绍如何使用 Python 的 Tkinter 库构建一个图形界面应用程序,它能够帮助用户快速地将长文本分割为指定长度的小段,并提供复制和保存功能。

工具特性

  • 输入文本:用户可以在一个大的文本框中输入或粘贴待分割的文本。
  • 字符计数:实时显示当前输入文本的总字符数。
  • 设置分割长度:用户可以自定义每个小段文本的字符数。
  • 分割按钮:点击后将文本按设定长度分割,并展示每个段落。
  • 复制按钮:对于每个分割后的段落,都有一个按钮可以将该段落复制到剪贴板。
  • 保存单个段落:允许用户单独保存某个段落到文件。
  • 保存所有段落:一键保存所有分割后的段落到指定目录下的多个文件中。
  • 清空按钮:清除所有输入和分割结果,重新开始。
import tkinter as tk
from tkinter import messagebox, ttk, filedialog
import pyperclip
import os


def onFrameConfigure(canvas):
    """Reset the scroll region to encompass the inner frame"""
    canvas.configure(scrollregion=canvas.bbox("all"))


def split_text():
    # 清空之前的小文本框和复制按钮
    clear_text_boxes()

    # 获取输入框中的文本
    input_text = input_entry.get("1.0", tk.END).strip()

    if not input_text:
        messagebox.showwarning("警告", "请输入要分割的文本")
        return

    # 获取每个段落的字符数
    try:
        segment_length = int(segment_length_var.get())
        if segment_length <= 0:
            raise ValueError
    except ValueError:
        messagebox.showwarning("警告", "请输入有效的正整数作为每个段落的字符数")
        return

    # 分割文本
    segments = [
        input_text[i : i + segment_length]
        for i in range(0, len(input_text), segment_length)
    ]

    # 创建小文本框和复制按钮
    for i, segment in enumerate(segments):
        create_text_box(segment, i)

    status_label.config(text=f"已分割为 {len(segments)} 段文本")


def create_text_box(text, index):
    global canvas_frame

    # 创建一个 Frame 来容纳文本框、字符数和复制按钮
    frame = tk.Frame(canvas_frame)
    frame.pack(padx=10, pady=5, anchor="w")

    # 显示序号
    index_label = tk.Label(frame, text=f"段落 {index + 1}:")
    index_label.pack(side=tk.LEFT)

    # 创建小文本框
    text_box = tk.Text(frame, height=5, width=50, wrap=tk.WORD)
    text_box.insert(tk.END, text)
    text_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    # 显示字符数
    character_count = len(text)
    count_label = tk.Label(frame, text=f"字符数: {character_count}")
    count_label.pack(side=tk.LEFT)

    # 创建复制按钮
    copy_button = tk.Button(frame, text="复制文本", command=lambda t=text: copy_text(t))
    copy_button.pack(side=tk.RIGHT)

    # 创建保存单个段落按钮
    save_button = tk.Button(
        frame, text="保存段落", command=lambda t=text, i=index: save_single_text(t, i)
    )
    save_button.pack(side=tk.RIGHT)


def copy_text(text):
    # 复制文本到剪贴板
    pyperclip.copy(text)
    status_label.config(text="文本已复制到剪贴板")


def save_single_text(text, index):
    # 选择保存文件的位置
    file_path = filedialog.asksaveasfilename(
        defaultextension=".txt",
        filetypes=[("Text files", "*.txt"), ("All files", "*.*")],
        initialfile=f"段落{index + 1}.txt",
    )
    if file_path:
        with open(file_path, "w", encoding="utf-8") as file:
            file.write(text)
        status_label.config(text=f"段落 {index + 1} 已保存到 {file_path}")


def save_all_text():
    global canvas_frame

    # 获取所有分割后的文本
    all_text = []
    for widget in canvas_frame.winfo_children():
        if isinstance(widget, tk.Frame):
            text_box = widget.winfo_children()[1]  # 小文本框是第二个子控件
            all_text.append((text_box, widget))

    # 选择保存文件夹的位置
    folder_path = filedialog.askdirectory()
    if folder_path:
        for i, (text_box, frame) in enumerate(all_text):
            text = text_box.get("1.0", tk.END).strip()
            file_path = os.path.join(folder_path, f"段落{i + 1}.txt")
            with open(file_path, "w", encoding="utf-8") as file:
                file.write(text)
        status_label.config(text=f"所有文本已保存到 {folder_path}")


def clear_text_boxes():
    global canvas_frame

    # 清空之前的小文本框和复制按钮
    for widget in canvas_frame.winfo_children():
        if isinstance(widget, tk.Frame):
            widget.destroy()


def clear_all():
    # 清空输入框和生成的小文本框
    input_entry.delete("1.0", tk.END)
    clear_text_boxes()
    status_label.config(text="已清空所有内容")


def count_characters(event):
    # 计算输入文本的字符数并显示
    input_text = input_entry.get("1.0", tk.END).strip()
    character_count = len(input_text)
    count_label.config(text=f"总字符数: {character_count}")


# 创建主窗口
root = tk.Tk()
root.title("文本分割程序")

# 设置窗口大小
root.geometry("720x520")

# 创建文本输入框
input_label = tk.Label(root, text="输入文本:")
input_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
input_entry = tk.Text(root, height=10, width=50, wrap=tk.WORD)
input_entry.grid(row=1, column=0, columnspan=4, padx=10, pady=5, sticky="nsew")
input_entry.bind("<KeyRelease>", count_characters)  # 绑定事件,实时更新字符数

# 添加滚动条
input_scrollbar = ttk.Scrollbar(root, orient=tk.VERTICAL, command=input_entry.yview)
input_entry.configure(yscrollcommand=input_scrollbar.set)
input_scrollbar.grid(row=1, column=4, sticky="ns")

# 创建分割长度输入框
segment_length_label = tk.Label(root, text="每个段落的字符数:")
segment_length_label.grid(row=2, column=0, padx=10, pady=5, sticky="w")
segment_length_var = tk.StringVar(value="5900")  # 默认值
segment_length_entry = tk.Entry(root, textvariable=segment_length_var, width=10)
segment_length_entry.grid(row=2, column=1, padx=10, pady=5, sticky="w")

# 创建分割按钮
split_button = tk.Button(root, text="分割", command=split_text)
split_button.grid(row=2, column=2, padx=10, pady=5, sticky="e")

# 创建清空按钮
clear_button = tk.Button(root, text="清空", command=clear_all)
clear_button.grid(row=2, column=3, padx=10, pady=5, sticky="e")

# 显示总字符数
count_label = tk.Label(root, text="总字符数: 0")
count_label.grid(row=0, column=2, padx=10, pady=5, sticky="e")

# 创建保存所有文本按钮
save_all_button = tk.Button(root, text="保存所有文本段落", command=save_all_text)
save_all_button.grid(row=2, column=4, padx=10, pady=5, sticky="e")

# 状态栏
status_label = tk.Label(root, text="", bd=1, relief=tk.SUNKEN, anchor=tk.W)
status_label.grid(row=100, column=0, columnspan=5, sticky="ew")

# 创建 Canvas 和 Scrollbar
canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
canvas_frame = tk.Frame(canvas, background="#ffffff")
vsb = tk.Scrollbar(root, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)

vsb.grid(row=3, column=4, sticky="ns")
canvas.grid(row=3, column=0, columnspan=4, sticky="nsew")
canvas.create_window((4, 4), window=canvas_frame, anchor="nw")

canvas_frame.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas))

# 使列和行自动扩展
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(3, weight=1)

# 运行主循环
root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896937.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL数据库操作——(4)

目录 8 视图 8.1 常见的数据库对象 8.2 视图概述 8.2.1 为什么使用视图&#xff1f; 8.2.2 视图的理解 8.3 创建视图 8.3.1 创建单表视图 8.3.2 创建多表联合视图 8.3.3 基于视图创建视图 8.4 查看视图 8.5 更新视图的数据 8.5.1 一般情况 8.6 修改、删除视图 8.…

Linux kernel 堆溢出利用方法

前言 本文还是用一道例题来讲解几种内核堆利用方法&#xff0c;内核堆利用手段比较多&#xff0c;可能会分三期左右写。进行内核堆利用前&#xff0c;可以先了解一下内核堆的基本概念&#xff0c;当然更好去找一些详细的内核堆的基础知识。 概述 Linux kernel 将内存分为 页…

数据结构_day3

目录 4.栈 stack 4.2.1 特性 练习&#xff1a; 4.3 链式栈 4.3.1 特性 总结&#xff1a; 4.栈 stack 4.2.1 特性 逻辑结构&#xff1a;线性结构 存储结构&#xff1a;顺序结构 操作&#xff1a;创建、入栈、出栈、判空和判满 创空&#xff1a; 入栈&#xff1a; 出栈&#xff1…

【自然语言处理】多头注意力机制 Multi-Head Attention

多头注意力&#xff08;Multi-Head Attention&#xff09;机制是Transformer模型中的一个关键组件&#xff0c;广泛用于自然语言处理任务&#xff08;如机器翻译、文本生成等&#xff09;以及图像处理任务。它的核心思想是通过多个不同的注意力头来捕获输入的不同特征&#xff…

虚拟现实与Facebook的结合:未来社交的全新体验

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术正在逐步改变人们的社交方式。Facebook&#xff0c;作为全球最大的社交媒体平台之一&#xff0c;积极探索如何将虚拟现实融入其社交生态系统&#xff0c;创造全新的用户体验。这一结合不仅影响了用户之间…

深度解析机器学习的四大核心功能:分类、回归、聚类与降维

深度解析机器学习的四大核心功能&#xff1a;分类、回归、聚类与降维 前言分类&#xff08;Classification&#xff09;&#xff1a;预测离散标签的艺术关键算法与代码示例逻辑回归支持向量机&#xff08;SVM&#xff09; 回归&#xff08;Regression&#xff09;&#xff1a;预…

探索秘境:如何使用智能体插件打造专属的小众旅游助手『小众旅游探险家』

文章目录 摘要引言智能体介绍和亮点展示介绍亮点展示 已发布智能体运行效果智能体创意想法创意想法创意实现路径拆解 如何制作智能体可能会遇到的几个问题快速调优指南总结未来展望 摘要 本文将详细介绍如何使用智能体平台开发一款名为“小众旅游探险家”的旅游智能体。通过这…

获取非加密邮件协议中的用户名和密码——安全风险演示

引言 在当今的数字时代,网络安全变得越来越重要。本文将演示如何通过抓包工具获取非加密邮件协议中的用户名和密码,以此说明使用非加密协议的潜在安全风险。通过这个演示,我们希望能提高读者的安全意识,促使大家采取更安全的通信方式。 注意: 本文仅用于教育目的,旨在提高安全…

【MyBatis】初识MyBatis 构建简单框架

目录 MyBatis前言搭建一个简单的MyBatis创建Maven项目引入必要依赖创建数据表结构创建User实体类创建Mapper接口Mapper层Dao层 创建MyBatis的Mapper映射文件编写测试类传统测试类JUnit测试 MyBatis 介绍&#xff1a;MyBatis是一款半自动的ORM持久层框架&#xff0c;具有较高的…

Linux下ClamAV源代码安装与使用说明

Linux下ClamAV源代码安装与使用说明 ClamAV(Clam AntiVirus)是一款开源的防病毒工具,广泛应用于Linux平台上的网络安全领域。它以其高效的性能和灵活的配置选项,成为网络安全从业人员的重要工具。ClamAV支持多线程扫描,可以自动升级病毒库,并且支持多个操作系统,包括Li…

NGINX 保护 Web 应用安全之基于 IP 地址的访问

根据客户端的 IP 地址控制访问 使用 HTTP 或 stream 访问模块控制对受保护资源的访问&#xff1a; location /admin/ { deny 10.0.0.1; allow 10.0.0.0/20; allow 2001:0db8::/32; deny all; } } 给定的 location 代码块允许来自 10.0.0.0/20 中的任何 IPv4 地址访问&#xf…

可视化大屏中运用3D模型,能够带来什么好处。

现在你看到的可视化大屏&#xff0c;大都会在中间放置一些3D模型&#xff0c;比如厂房、园区、设备等等&#xff0c;那么这些3D模型的放置的确给可视化大屏带来了不一样的视觉冲击&#xff0c;本文将从以下四个方面来分析这个现象。 一、可视化大屏中越来越多使用3D模型说明了…

Linux工具的使用-【git的理解和使用】【调试器gdb的使用】

目录 Linux工具的使用-031.git1.1git是什么1.2git在linux下的操作1.2.1创建git仓库1.2.2 .gitignore1.2.3 .git&#xff08;本地仓库&#xff09;1.2.4 add (添加)1.2.5 commit(提交)1.2.6push(推送)对两个特殊情况的处理配置免密码push 1.2.7 log(获取提交记录)1.2.8 status(获…

Java项目-基于springboot框架的逍遥大药房管理系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

Linux运维篇-误操作已经做了pv的磁盘导致pv异常

目录 故障场景排错过程小结 故障场景 在对/dev/vdb1创建了pv并扩容至vg(klas)之后&#xff0c;不小心对/dev/vdb进行了parted操作&#xff0c;删除了/dev/vdb1导致pvs查看显示异常。具体过程如下所示&#xff1a; 正常创建pv 将创建好的pv添加到系统现有的卷组中 不小心又对…

Golang | Leetcode Golang题解之第491题非递减子序列

题目&#xff1a; 题解&#xff1a; var (temp []intans [][]int )func findSubsequences(nums []int) [][]int {ans [][]int{}dfs(0, math.MinInt32, nums)return ans }func dfs(cur, last int, nums []int) {if cur len(nums) {if len(temp) > 2 {t : make([]int, len(…

【计网】理解TCP全连接队列与tcpdump抓包

希望是火&#xff0c;失望是烟&#xff0c; 生活就是一边点火&#xff0c;一边冒烟。 理解TCP全连接队列与tcpdump抓包 1 TCP 全连接队列1.1 重谈listen函数1.2 初步理解全连接队列1.3 深入理解全连接队列 2 tcpdump抓包 1 TCP 全连接队列 1.1 重谈listen函数 这里我们使用…

颜色交替的最短路径

题目链接 颜色交替的最短路径 题目描述 注意 返回长度为n的数组answer&#xff0c;其中answer[x]是从节点0到节点x的红色边和蓝色边交替出现的最短路径的长度图中每条边为红色或者蓝色&#xff0c;且可能存在自环或平行边 解答思路 可以使用广度优先遍历从0开始找到其相邻…

Java.6--多态-设计模式-抽象父类-抽象方法

一、多态 1.定义--什么是多态&#xff1f; a.同一个父类的不同子类对象&#xff0c;在做同一行为的时候&#xff0c;有不同的表现形式&#xff0c;这就是多态。&#xff08;总结为&#xff1a;一个父类下的不同子类&#xff0c;同一行为&#xff0c;不同表现形式。&#xff0…