我试图在我的Mac Lion上使用Python脚本获取剪贴板内容。剪贴板内容发生更改时触发事件
我正在寻找一个事件或类似的东西,因为如果我使用循环,我的应用程序将花费所有的时间来观看剪贴板。
任何想法?
我试图在我的Mac Lion上使用Python脚本获取剪贴板内容。剪贴板内容发生更改时触发事件
我正在寻找一个事件或类似的东西,因为如果我使用循环,我的应用程序将花费所有的时间来观看剪贴板。
任何想法?
你有没有想过使用无限循环和尝试之间的“睡眠”? 我用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
,做你想做的。如果您需要多线程帮助将其放入后台线程中,请告诉我。
EDIT
下面是一个完整的多线程例子。
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)
。
望着pyperclip
它的MacOSX上的肉:
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()
我正在使用Appkit框架:'NSPasteboard.generalPasteboard()',我需要循环来立即得到新的剪贴板内容..因为我没有剪贴板的回调事件。 –
的Python 3代码(https://stackoverflow.com/a/14687465/4258588):
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)
PS-我不能为它添加注释由于低信誉分的话,我将以此为回答。
这段代码与之前发布的代码是99%相同的,唯一的区别是python3风格的'print()',并不真的值得单独回答 – jps
谢谢,是请告诉我如何做到这一点在后台线程我的循环看起来像这样:'而真: \t \t \t pbstring = checkclipboard() \t \t \t如果的 'http://' 在pbstring和pbstring不是 'bit.ly': \t \t \t \t bitly(pbstring,用户名,键) \t \t \t \t \t \t其他: \t \t \t \t打印的等待......“ \t \t \t \t打印pbstring \t \t \t \t time.sleep(5)'所以此刻我对循环整个应用程序等待,我不能同时做任何事情。 。 –
我创建了一个扩展示例,包括多线程。 –
你的脚本看起来不错。你注意剪贴板中的URL,如果你找到了,用一个缩短的版本替换它? –