我正在尝试使用Mac Lion上的Python脚本获取剪贴板内容。
我正在搜索类似的事件,因为如果我使用循环,我的应用程序会花费所有时间来查看剪贴板。
有什么想法吗?
答案 0 :(得分:16)
您是否考虑过使用无限循环并在尝试之间“休眠”? 我使用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)
。
答案 1 :(得分:3)
上述答案的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-由于信誉度低,我无法将其添加为评论,因此,我将其添加为答案。
答案 2 :(得分:1)
在Macosx上查看pyperclip
它的内容是:
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()
答案 3 :(得分:0)
简单!
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