18

我正在尝试在我的 Mac Lion 上使用 Python 脚本获取剪贴板内容。

我正在搜索一个事件或类似的东西,因为如果我使用循环,我的应用程序会花费所有时间查看剪贴板。

有任何想法吗?

4

3 回答 3

20

您是否考虑过使用无限循环并在尝试之间“休眠”?我将pyperclip用于一个简单的 PoC,它就像一个魅力,以及 Windows 和 Linux。

import time
import sys
import os
sys.path.append(os.path.abspath("SO_site-packages"))

import pyperclip

recent_value = ""
while True:
    tmp_value = pyperclip.paste()
    if tmp_value != recent_value:
        recent_value = tmp_value
        print("Value changed: %s" % str(recent_value)[:20])
    time.sleep(0.1)

而不是print,做任何你想做的事。如果您需要多线程方面的帮助才能将其放入后台线程,请告诉我。

编辑

这是一个完整的多线程示例。

import time
import threading

import pyperclip

def is_url_but_not_bitly(url):
    if url.startswith("http://") and not "bit.ly" in url:
        return True
    return False

def print_to_stdout(clipboard_content):
    print ("Found url: %s" % str(clipboard_content))

class ClipboardWatcher(threading.Thread):
    def __init__(self, predicate, callback, pause=5.):
        super(ClipboardWatcher, self).__init__()
        self._predicate = predicate
        self._callback = callback
        self._pause = pause
        self._stopping = False

    def run(self):       
        recent_value = ""
        while not self._stopping:
            tmp_value = pyperclip.paste()
            if tmp_value != recent_value:
                recent_value = tmp_value
                if self._predicate(recent_value):
                    self._callback(recent_value)
            time.sleep(self._pause)

    def stop(self):
        self._stopping = True

def main():
    watcher = ClipboardWatcher(is_url_but_not_bitly, 
                               print_to_stdout,
                               5.)
    watcher.start()
    while True:
        try:
            print("Waiting for changed clipboard...")
            time.sleep(10)
        except KeyboardInterrupt:
            watcher.stop()
            break


if __name__ == "__main__":
    main()

我创建了一个 threading.Thread 的子类,覆盖了这些方法run__init__创建了这个类的一个实例。通过调用watcher.start()(不是run()!),您启动线程。

为了安全地停止线程,我等待 -c (键盘中断)并告诉线程自行停止。

在类的初始化中,您还有一个参数pause来控制尝试之间的等待时间。

像在我的示例中一样使用类 ClipboardWatcher,将回调替换为您所做的,例如lambda x: bitly(x, username, password).

于 2013-02-04T13:09:53.007 回答
2

pyperclipMacosx 上查看它的实质是:

import os
def macSetClipboard(text):
    outf = os.popen('pbcopy', 'w')
    outf.write(text)
    outf.close()

def macGetClipboard():
    outf = os.popen('pbpaste', 'r')
    content = outf.read()
    outf.close()
    return content

这些对我有用,你过得怎么样?

我不太听从你关于处于循环中的评论。


编辑添加了 'orrid 轮询示例,显示如何changeCount()在每个copy粘贴板上颠簸。这仍然不是 OP 想要的,因为似乎没有任何事件或通知来修改NSPasteboard.

from LaunchServices import *
from AppKit import *
import os

from threading import Timer

def poll_clipboard():
    pasteboard = NSPasteboard.generalPasteboard()
    print pasteboard.changeCount()

def main():
    while True:
        t = Timer(1, poll_clipboard)
        t.start()
        t.join()

if __name__ == "__main__":
    main()
于 2013-02-04T13:45:21.903 回答
1

简单的!

import os
def macSetClipboard(text):
    outf = os.popen('pbcopy', 'w')
    outf.write(text)
    outf.close()

def macGetClipboard():
    outf = os.popen('pbpaste', 'r')
    content = outf.read()
    outf.close()
    return content
current_clipboard = macGetClipboard()
while True:
   clipboard = macGetClipboard()
   
   if clipboard != current_clipboard:
       print(clipboard)
       macSetClipboard("my new string")
       print(macGetClipboard())
       break
于 2020-12-15T04:52:30.447 回答