仿制PopClip出现的问题,有没有大佬帮忙?

选中后点击复制不能生效,需要怎么解决?
下面是代码

from pynput import mouse
import tkinter as tk
from threading import Thread
import queue
import pyautogui
from pynput.keyboard import Key, Controller


class DragListener:
    def __init__(self):
        self.status_label = None
        self.drag_threshold = 10  # 像素阈值
        self.dragging = False
        self.start_x = 0
        self.start_y = 0
        self.queue = queue.Queue()
        self.root = tk.Tk()
        self.root.title("牛子小能手")
        self.has_dragged = False  # 新增:标记是否发生拖动
        self.root.withdraw()  # 隐藏主窗口
        self.tooltip = None  # 提示窗口
        self.keyboard = Controller()

        # 设置 pyautogui 的安全暂停时间
        pyautogui.PAUSE = 0.5

    def on_click(self, x, y, button, pressed):
        if button == mouse.Button.left:
            if pressed:
                self.has_dragged = False
                self.dragging = True
                self.start_x = x
                self.start_y = y
            else:
                self.dragging = False
                self.queue.put((x, y))  # 将坐标放入队列
                if self.has_dragged:
                    mouse_x, mouse_y = pyautogui.position()
                    self._show_button(mouse_x, mouse_y)

    def on_move(self, x, y):
        if self.dragging and not self.has_dragged:
            distance = ((x - self.start_x) ** 2 + (y - self.start_y) ** 2) ** 0.5
            if distance > self.drag_threshold:
                self.has_dragged = True

    def start_listening(self):
        # 启动鼠标监听线程
        listener_thread = Thread(target=self._listen_mouse)
        listener_thread.daemon = True
        listener_thread.start()
        # 在主线程处理 Tkinter 事件
        self.root.mainloop()

    def _listen_mouse(self):
        with mouse.Listener(on_click=self.on_click, on_move=self.on_move) as listener:
            listener.join()



    def _on_action_button_click_copy(self, top_window):
        # 延迟 100ms 后按下 'a' 键
        self.root.after(100, lambda: self.keyboard.press(Key.cmd))
        self.root.after(200, lambda: self.keyboard.press('c'))
        # 延迟 200ms 后释放 'a' 键
        self.root.after(300, lambda: self.keyboard.release('c'))
        self.root.after(400, lambda: self.keyboard.release(Key.cmd))

        self.has_dragged = False  # 重置拖动状态标记
        top_window.destroy()  # 销毁按钮窗口

    def _show_button(self, x, y):
        top = tk.Toplevel(self.root)
        top.geometry(f"+{x}+{y}")  # 定位到鼠标释放位置

        # 创建按钮容器(水平排列两个按钮)
        button_frame = tk.Frame(top)
        button_frame.pack(padx=6, pady=5)

        # 功能按钮(原"点击我"按钮)
        action_btn = tk.Button(
            button_frame,
            text="复制",
            command=lambda: self._on_action_button_click_copy(top),
        )
        action_btn.pack(side="left", padx=2)

        # 窗口样式优化
        top.attributes("-topmost", True)  # 确保窗口在最前
        top.resizable(False, False)  # 禁止调整大小


if __name__ == "__main__":
    listener = DragListener()
    listener.start_listening()

你是mac还是windows?

Mac

试试看pynput的hotkey模块,一般输快捷键的话推荐用这个

感谢回复

期待整个Windows的

这个代码现在好像是光标聚焦问题。hotkey也不能生效

有机会的话

微进步,龟速进行。
目前可以复制macos的备忘录的字符串了大伙可以尝试一下

from pynput import mouse
import tkinter as tk
from threading import Thread
import queue
import pyautogui
import oktestgetpid
import subprocess

from ApplicationServices import (
    AXUIElementCreateApplication,
    AXUIElementCopyAttributeValue,
    kAXFocusedUIElementAttribute,
    AXUIElementCopyAttributeNames
)


class DragListener:
    def __init__(self):
        self.status_label = None
        self.drag_threshold = 10  # 像素阈值
        self.dragging = False
        self.start_x = 0
        self.start_y = 0
        self.queue = queue.Queue()
        self.root = tk.Tk()
        self.root.title("牛子小能手")
        self.has_dragged = False  # 新增:标记是否发生拖动
        self.root.withdraw()  # 隐藏主窗口
        self.tooltip = None  # 提示窗口

        # 设置 pyautogui 的安全暂停时间
        pyautogui.PAUSE = 0.5

    def on_click(self, x, y, button, pressed):
        if button == mouse.Button.left:
            if pressed:
                self.has_dragged = False
                self.dragging = True
                self.start_x = x
                self.start_y = y
            else:
                self.dragging = False
                self.queue.put((x, y))  # 将坐标放入队列
                if self.has_dragged:
                    pid = oktestgetpid.getCruntPid()
                    mouse_x, mouse_y = pyautogui.position()
                    self._show_button(mouse_x, mouse_y,pid)

    def on_move(self, x, y):
        if self.dragging and not self.has_dragged:
            distance = ((x - self.start_x) ** 2 + (y - self.start_y) ** 2) ** 0.5
            if distance > self.drag_threshold:
                self.has_dragged = True

    def start_listening(self):
        # 启动鼠标监听线程
        listener_thread = Thread(target=self._listen_mouse)
        listener_thread.daemon = True
        listener_thread.start()
        # 在主线程处理 Tkinter 事件
        self.root.mainloop()

    def _listen_mouse(self):
        with mouse.Listener(on_click=self.on_click, on_move=self.on_move) as listener:
            listener.join()

    def get_app_name_by_pid(self,pid):
        try:
            # 执行 ps 命令,获取进程的命令名称
            result = subprocess.run(['ps', '-p', str(pid), '-o', 'comm='],capture_output=True, text=True, check=True)
            app_name = result.stdout.strip()
            print(app_name)
            return app_name if app_name else "未找到对应进程"
        except subprocess.CalledProcessError:
            return "无效的 PID 或进程不存在"

    def _on_action_button_click_copy(self, top_window,pid):
        self.has_dragged = False  # 重置拖动状态标记
        # 创建 AXUIElementRef 对象
        app_ref = AXUIElementCreateApplication(pid)
        # 获取当前聚焦的 UI 元素
        result = AXUIElementCopyAttributeValue(app_ref, kAXFocusedUIElementAttribute, None)
        # 解包并调整返回值
        first, second = result
        if isinstance(first, int):
            error, focused_element = first, second
        elif isinstance(second, int):
            focused_element, error = first, second
        else:
            print("无法解析返回值")
            exit(1)
        # 从聚焦元素中获取选中文本 (AXSelectedText)
        attributes = AXUIElementCopyAttributeNames(focused_element,None)
        print(attributes)
        text_result = AXUIElementCopyAttributeValue(focused_element, "AXStaticText", None)
        text_value, text_error = text_result
        print(text_error)
        print(text_value)
        top_window.destroy()  # 销毁按钮窗口

    def _show_button(self, x, y,pid):
        top = tk.Toplevel(self.root)
        top.geometry(f"+{x}+{y}")  # 定位到鼠标释放位置

        # 创建按钮容器(水平排列两个按钮)
        button_frame = tk.Frame(top)
        button_frame.pack(padx=6, pady=5)

        # 功能按钮(原"点击我"按钮)
        action_btn = tk.Button(
            button_frame,
            text="复制",
            command=lambda: self._on_action_button_click_copy(top,pid),
        )
        action_btn.pack(side="left", padx=2)

        # 关闭按钮(新增功能)
        close_btn = tk.Button(
            button_frame,
            text="删除",
            command=lambda :self._on_action_button_click_copy(top),
            bg="#ff9999",  # 红色背景更显眼
            activebackground="#ff6666"
        )
        close_btn.pack(side="left", padx=2)


        # 关闭按钮(新增功能)
        cut_btn = tk.Button(
            button_frame,
            text="剪切",
            command=lambda :self._on_action_button_click_copy(top),
            bg="#ff9999",  # 红色背景更显眼
            activebackground="#ff6666"
        )
        cut_btn.pack(side="left", padx=2)

        # 窗口样式优化
        top.attributes("-topmost", True)  # 确保窗口在最前
        top.resizable(False, False)  # 禁止调整大小



if __name__ == "__main__":
    listener = DragListener()
    listener.start_listening()

可以直接用python开发macOS的软件吗,不是要用Xcode吗?

这是两回事吧?Python 是一种编程语言,只要安装了开发环境,在哪儿都可以运行用 Python 编写的程序。Xcode 只是一套开发工具。

这个看开发习惯

:+1:麻烦完善一下代码

您回错人了吧?我没有提代码啊……