通信小程序(九)快捷键自动改名

'''

注意事项:

程序会自动保存设置到 rename_settings.json 文件中,下次启动时会加载之前的设置。

  1. 程序需要相应的权限来模拟键盘输入

  2. 在其他Linux系统上可能需要安装额外的依赖:

复制代码
sudo apt-get install python3-tk python3-dev
sudo apt-get install xclip xsel
  1. 某些Linux桌面环境可能需要配置权限才能进行全局热键监听

  2. 自定义按键时,请使用pyautogui支持的按键名称(如:'f2', 'right', 'enter', 'a', 'b'等)

描述:一个统信linux中运行的一个名叫重命名的python程序,通过tktinter输入参数,界面尺寸300*250,底色淡黄色,一键处理的按键是糖果绿色,字体:fangsong ti,字号12号。

程序开始运行时,等待Ctrl+B为触发功能,执行以下命令,执行完毕后自动进入下一次等待触发。具体是打开资源管理器触发功能后,自动将选中的文件通过该F2进入改名状态

功能1:输入每组连点的间隔,默认值1s,输入默认连点次数,默认1次。

功能2:输入连点键输入框,通过输入按键代码及间隔时间,实现一组连续输入。默认是:执行"F2",然后间隔0.5秒,然后执行"向右方健健"。注意,这三步就是一组连续输入。注意,也可选择改为其他键盘按键连点。

功能3:可以点击浅绿开始键,则也能开始连点,点击浅红结束键,则自动结束连点。

'''

复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk, messagebox
import time
import threading
import subprocess
import sys
import os
from pynput import keyboard
import pyautogui
import json
class RenameAssistant:
    def __init__(self, root):
        self.root = root
        self.root.title("重命名助手")
        self.root.geometry("450x300")
        self.root.configure(bg='#FFFFE0')  # 淡黄色背景
        self.root.resizable(False, False)

        # 监听状态
        self.listening = False
        self.running = False
        self.hotkey_listener = None

        # 默认设置
        self.default_settings = {
            'interval': 1.0,
            'repeat_count': 1,
            'sequence': [
                {'key': 'f2', 'interval': 0.5},
                {'key': 'right', 'interval': 0.1}
            ]
        }

        # 加载设置
        self.settings = self.load_settings()

        # 设置字体
        self.font = ('Fangsong Ti', 12)

        self.setup_ui()
        self.start_hotkey_listener()

        # 窗口关闭时清理
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

    def setup_ui(self):
        # 主框架
        main_frame = tk.Frame(self.root, bg='#FFFFE0')
        main_frame.pack(fill='both', expand=True, padx=10, pady=10)

        # 功能1:间隔时间和重复次数
        frame1 = tk.Frame(main_frame, bg='#FFFFE0')
        frame1.pack(fill='x', pady=5)

        tk.Label(frame1, text="间隔时间(秒):", bg='#FFFFE0', font=self.font).pack(side='left')
        self.interval_var = tk.StringVar(value=str(self.settings['interval']))
        interval_entry = tk.Entry(frame1, textvariable=self.interval_var, width=10, font=self.font)
        interval_entry.pack(side='left', padx=5)

        tk.Label(frame1, text="重复次数:", bg='#FFFFE0', font=self.font).pack(side='left', padx=(10, 0))
        self.repeat_var = tk.StringVar(value=str(self.settings['repeat_count']))
        repeat_entry = tk.Entry(frame1, textvariable=self.repeat_var, width=10, font=self.font)
        repeat_entry.pack(side='left', padx=5)

        # 功能2:按键序列设置
        frame2 = tk.Frame(main_frame, bg='#FFFFE0')
        frame2.pack(fill='x', pady=5)

        tk.Label(frame2, text="按键序列:", bg='#FFFFE0', font=self.font).pack(anchor='w')

        # 创建按键序列显示区域
        self.sequence_frame = tk.Frame(frame2, bg='#FFFFE0')
        self.sequence_frame.pack(fill='x', pady=5)
        self.update_sequence_display()

        # 添加新按键按钮
        add_btn = tk.Button(frame2, text="添加按键", command=self.add_key_sequence,
                            bg='#E0E0E0', font=self.font)
        add_btn.pack(side='left', padx=2)

        # 重置按钮
        reset_btn = tk.Button(frame2, text="重置默认", command=self.reset_to_default,
                              bg='#E0E0E0', font=self.font)
        reset_btn.pack(side='left', padx=2)

        # 保存设置按钮
        save_btn = tk.Button(frame2, text="保存设置", command=self.save_settings,
                             bg='#E0E0E0', font=self.font)
        save_btn.pack(side='left', padx=2)

        # 功能3:控制按钮
        frame3 = tk.Frame(main_frame, bg='#FFFFE0')
        frame3.pack(fill='x', pady=10)

        # 糖果绿色开始按钮
        self.start_btn = tk.Button(frame3, text="开始执行", command=self.start_execution,
                                   bg='#98FB98', fg='black', font=self.font,
                                   activebackground='#7CFC00', width=10)
        self.start_btn.pack(side='left', padx=10)

        # 浅红色结束按钮
        self.stop_btn = tk.Button(frame3, text="结束执行", command=self.stop_execution,
                                  bg='#FFB6C1', fg='black', font=self.font,
                                  activebackground='#FF69B4', width=10)
        self.stop_btn.pack(side='left', padx=10)

        # 状态标签
        self.status_label = tk.Label(main_frame, text="状态: 等待Ctrl+B触发",
                                     bg='#FFFFE0', font=self.font)
        self.status_label.pack(pady=5)

        # 监听状态标签
        self.hotkey_status = tk.Label(main_frame, text="热键监听: 运行中",
                                      bg='#FFFFE0', font=('Fangsong Ti', 10))
        self.hotkey_status.pack()

    def update_sequence_display(self):
        # 清空现有显示
        for widget in self.sequence_frame.winfo_children():
            widget.destroy()

        # 显示当前序列
        for i, step in enumerate(self.settings['sequence']):
            step_frame = tk.Frame(self.sequence_frame, bg='#FFFFE0')
            step_frame.pack(fill='x', pady=2)

            tk.Label(step_frame, text=f"步骤{i + 1}:", bg='#FFFFE0',
                     font=('Fangsong Ti', 10)).pack(side='left')
            tk.Label(step_frame, text=f"按键: {step['key']}", bg='#FFFFE0',
                     font=('Fangsong Ti', 10)).pack(side='left', padx=5)
            tk.Label(step_frame, text=f"间隔: {step['interval']}秒", bg='#FFFFE0',
                     font=('Fangsong Ti', 10)).pack(side='left', padx=5)

            # 删除按钮
            del_btn = tk.Button(step_frame, text="X", command=lambda idx=i: self.remove_step(idx),
                                bg='#FF9999', font=('Fangsong Ti', 8), width=2)
            del_btn.pack(side='right')

    def add_key_sequence(self):
        # 创建添加按键的对话框
        dialog = tk.Toplevel(self.root)
        dialog.title("添加按键步骤")
        dialog.geometry("300x150")
        dialog.configure(bg='#FFFFE0')
        dialog.resizable(False, False)

        tk.Label(dialog, text="按键代码:", bg='#FFFFE0', font=self.font).pack(pady=5)
        key_var = tk.StringVar()
        key_entry = tk.Entry(dialog, textvariable=key_var, font=self.font, width=20)
        key_entry.pack(pady=5)
        key_entry.insert(0, "f2")

        tk.Label(dialog, text="间隔时间(秒):", bg='#FFFFE0', font=self.font).pack(pady=5)
        interval_var = tk.StringVar(value="0.5")
        interval_entry = tk.Entry(dialog, textvariable=interval_var, font=self.font, width=10)
        interval_entry.pack(pady=5)

        def save_step():
            key = key_var.get().strip().lower()
            try:
                interval = float(interval_var.get())
                if interval < 0.1:
                    interval = 0.1
            except:
                interval = 0.5

            self.settings['sequence'].append({'key': key, 'interval': interval})
            self.update_sequence_display()
            dialog.destroy()

        tk.Button(dialog, text="添加", command=save_step, bg='#98FB98',
                  font=self.font).pack(pady=10)

    def remove_step(self, index):
        if 0 <= index < len(self.settings['sequence']):
            self.settings['sequence'].pop(index)
            self.update_sequence_display()

    def reset_to_default(self):
        self.settings = self.default_settings.copy()
        self.interval_var.set(str(self.settings['interval']))
        self.repeat_var.set(str(self.settings['repeat_count']))
        self.update_sequence_display()
        messagebox.showinfo("重置", "已恢复默认设置")

    def save_settings(self):
        try:
            # 更新当前设置
            self.settings['interval'] = float(self.interval_var.get())
            self.settings['repeat_count'] = int(self.repeat_var.get())

            # 保存到文件
            with open('rename_settings.json', 'w') as f:
                json.dump(self.settings, f, indent=2)

            messagebox.showinfo("保存成功", "设置已保存到文件")
        except Exception as e:
            messagebox.showerror("保存失败", f"保存设置时出错: {str(e)}")

    def load_settings(self):
        try:
            if os.path.exists('rename_settings.json'):
                with open('rename_settings.json', 'r') as f:
                    return json.load(f)
        except:
            pass
        return self.default_settings.copy()

    def start_hotkey_listener(self):
        """启动热键监听"""
        self.listening = True
        self.hotkey_listener = keyboard.GlobalHotKeys({
            '<ctrl>+b': self.trigger_hotkey
        })
        self.hotkey_listener.start()

    def trigger_hotkey(self):
        """热键触发时的处理"""
        if not self.running:
            self.root.after(0, self._execute_rename_sequence)

    def _execute_rename_sequence(self):
        """执行重命名序列"""
        try:
            self.running = True
            self.status_label.config(text="状态: 执行中...")
            self.start_btn.config(state='disabled')

            # 获取当前设置
            interval = float(self.interval_var.get())
            repeat_count = int(self.repeat_var.get())

            # 获取当前选中的文件(通过模拟F2)
            # 首先模拟F2进入重命名模式
            time.sleep(0.1)  # 短暂延迟

            # 执行按键序列指定次数
            for _ in range(repeat_count):
                for step in self.settings['sequence']:
                    key = step['key']
                    # 处理特殊按键
                    if key == 'right':
                        pyautogui.press('right')
                    elif key == 'left':
                        pyautogui.press('left')
                    elif key == 'enter':
                        pyautogui.press('enter')
                    elif key == 'esc':
                        pyautogui.press('esc')
                    else:
                        pyautogui.press(key)

                    # 等待指定的间隔时间
                    time.sleep(step['interval'])

                # 每组之间的间隔
                if _ < repeat_count - 1:
                    time.sleep(interval)

        except Exception as e:
            messagebox.showerror("执行错误", f"执行过程中出错: {str(e)}")
        finally:
            self.running = False
            self.status_label.config(text="状态: 等待Ctrl+B触发")
            self.start_btn.config(state='normal')

    def start_execution(self):
        """手动开始执行"""
        if not self.running:
            threading.Thread(target=self._execute_rename_sequence, daemon=True).start()

    def stop_execution(self):
        """停止执行"""
        # 对于这种简单模拟,我们只能标记停止状态
        # 实际执行会在当前循环结束后停止
        if self.running:
            self.running = False
            self.status_label.config(text="状态: 正在停止...")

    def on_closing(self):
        """关闭窗口时的清理"""
        if self.hotkey_listener:
            self.hotkey_listener.stop()
        self.root.destroy()


def main():
    root = tk.Tk()
    app = RenameAssistant(root)
    root.mainloop()


if __name__ == "__main__":
    # 检查依赖
    try:
        import pyautogui
        from pynput import keyboard
    except ImportError:
        print("请先安装必要的依赖库:")
        print("pip install pyautogui pynput")
        sys.exit(1)

    main()
相关推荐
Mr. zhihao3 分钟前
深度解析 OpenAI Assistant API:从核心架构到实战场景
python·架构
~远在太平洋~5 分钟前
debian系统已安装python3.12却无法执行python命令
chrome·python·debian
老师用之于民6 分钟前
【DAY25】线程与进程通信:共享内存、同步机制及实现方案
linux·c语言·ubuntu·visual studio code
lldhsds9 分钟前
kvm虚拟化安装deepin desktop 25 磁盘空间过小弹窗显示为黑屏
linux
川trans9 分钟前
云原生--Nginx
linux·运维·服务器·nginx·云原生
2501_9419820510 分钟前
告别手动,Java 自动化调用企微外部群的深度实践
开发语言·python
txzz888813 分钟前
CentOS-Stream-10 Secure Shell服务器sshd_config配置文件
linux·centos·sshd_config·ssh配置
-Try hard-16 分钟前
线程间通信 | 避免资源竞争、实现同步通信
linux·开发语言·信息与通信
Nightmare00417 分钟前
切换conda环境的时候输出zstandard could not be imported. Running without .conda support.
开发语言·python·conda
Trouvaille ~18 分钟前
【项目篇】从零手写高并发服务器(一):项目介绍与开发环境搭建
linux·运维·服务器·网络·c++·高并发·muduo库